This commit is contained in:
moparisthebest 2014-04-15 13:40:50 -04:00
commit 69e0600052
6631 changed files with 956457 additions and 0 deletions

177
BUILDING.txt Normal file
View File

@ -0,0 +1,177 @@
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

83
DEVELOPING.txt Normal file
View File

@ -0,0 +1,83 @@
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

43
LICENSE.jsr173-api Normal file
View File

@ -0,0 +1,43 @@
BEA Systems, Inc. ("BEA")
Binary Code License Agreement
JSR 173 "Streaming API for XML" - Reference Implementation
READ THE TERMS OF THIS AGREEMENT AND ANY PROVIDED SUPPLEMENTAL LICENSE TERMS (COLLECTIVELY "AGREEMENT") CAREFULLY BEFORE OPENING THE SOFTWARE MEDIA PACKAGE.  BY OPENING THE SOFTWARE MEDIA PACKAGE, YOU AGREE TO THE TERMS OF THIS AGREEMENT.  IF YOU ARE ACCESSING THE SOFTWARE ELECTRONICALLY, INDICATE YOUR ACCEPTANCE OF THESE TERMS BY SELECTING THE "ACCEPT" BUTTON AT THE END OF THIS AGREEMENT.  IF YOU DO NOT AGREE TO ALL THESE TERMS, PROMPTLY RETURN THE UNUSED SOFTWARE TO YOUR PLACE OF PURCHASE FOR A REFUND OR, IF THE SOFTWARE IS ACCESSED ELECTRONICALLY, SELECT THE "DECLINE" BUTTON AT THE END OF THIS AGREEMENT.
1.  LICENSE TO USE.  BEA grants you a non-exclusive and non-transferable, royalty-free license for the internal use only of the accompanying software and documentation and any error corrections provided by BEA (collectively "Software").
2.  RESTRICTIONS.  Software is confidential and copyrighted. Title to Software and all associated intellectual property rights is retained by BEA and/or its licensors.  Except as specifically authorized in any Supplemental License Terms, you may not make copies of Software, other than a single copy of Software for archival purposes.  Unless enforcement is prohibited by applicable law, you may not modify, decompile, or reverse engineer Software.  Licensee acknowledges that Licensed Software is not designed or intended for use in the design, construction, operation or maintenance of any nuclear facility. BEA disclaims any express or implied warranty of fitness for such uses.   No right, title or interest in or to any trademark, service mark, logo or trade name of BEA or its licensors is granted under this Agreement.
3. LIMITED WARRANTY.  BEA warrants to you that for a period of ninety (90) days from the date of purchase, as evidenced by a copy of the receipt, the media on which Software is furnished (if any) will be free of defects in materials and workmanship under normal use.  Except for the foregoing, Software is provided "AS IS".  Your exclusive remedy and BEA's entire liability under this limited warranty will be at BEA's option to replace Software media or refund the fee paid for Software.
4.  DISCLAIMER OF WARRANTY.  UNLESS SPECIFIED IN THIS AGREEMENT, ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT THESE DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
5.  LIMITATION OF LIABILITY.  TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL BEA OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF BEA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  In no event will BEA's liability to you, whether in contract, tort (including negligence), or otherwise, exceed the amount paid by you for Software under this Agreement.  The foregoing limitations will apply even if the above stated warranty fails of its essential purpose.
6.  Termination.  This Agreement is effective until terminated.  You may terminate this Agreement at any time by destroying all copies of Software.  This Agreement will terminate immediately without notice from BEA if you fail to comply with any provision of this Agreement.  Upon Termination, you must destroy all copies of Software.
7. Export Regulations. All Software and technical data delivered under this Agreement are subject to US export control laws and may be subject to export or import regulations in other countries.  You agree to comply strictly with all such laws and regulations and acknowledge that you have the responsibility to obtain such licenses to export, re-export, or import as may be required after delivery to you.
8.  U.S. Government Restricted Rights.  If Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in Software and accompanying documentation will be only as set forth in this Agreement; this is in accordance with 48 CFR 227.7201 through 227.7202-4 (for Department of Defense (DOD) acquisitions) and with 48 CFR 2.101 and 12.212 (for non-DOD acquisitions).
9.  Governing Law.  Any action related to this Agreement will be governed by California law and controlling U.S. federal law.  No choice of law rules of any jurisdiction will apply.
10. Severability. If any provision of this Agreement is held to be unenforceable, this Agreement will remain in effect with the provision omitted, unless omission would frustrate the intent of the parties, in which case this Agreement will immediately terminate.
11. Integration.  This Agreement is the entire agreement between you and BEA relating to its subject matter.  It supersedes all prior or contemporaneous oral or written communications, proposals, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement.  No modification of this Agreement will be binding, unless in writing and signed by an authorized representative of each party.
JSR 173, REFERENCE IMPLEMENTATION
SUPPLEMENTAL LICENSE TERMS
These supplemental license terms ("Supplemental Terms") add to or modify the terms of the Binary Code License Agreement (collectively, the "Agreement"). Capitalized terms not defined in these Supplemental Terms shall have the same meanings ascribed to them in the Agreement. These Supplemental Terms shall supersede any inconsistent or conflicting terms in the Agreement, or in any license contained within the Software.
1. Software Internal Use and Development License Grant. Subject to the terms and conditions of this Agreement, BEA grants you a non-exclusive, non-transferable, limited license to reproduce internally and use internally the binary form of the Software, complete and unmodified, for the sole purpose of designing, developing and testing your Java applets and applications ("Programs").
2. License to Distribute Software.  In addition to the license granted in Section 1 (Software Internal Use and Development License Grant) of these Supplemental Terms, subject to the terms and conditions of this Agreement, BEA grants you a non-exclusive, non-transferable, limited license to reproduce and distribute the Software in binary form only, provided that you (i) distribute the Software complete and unmodified and only bundled as part of your Programs, (ii) do not distribute additional software intended to replace any component(s) of the Software, (iii) do not remove or alter any proprietary legends or notices contained in the Software, (iv) only distribute the Software subject to a license agreement that protects BEA's and its licensor<6F> interests consistent with the terms contained in this Agreement, and (v) agree to defend and indemnify BEA and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Software.
3. Source Code. Software may contain source code that is provided solely for reference purposes pursuant to the terms of this Agreement.  Such source code may not be redistributed unless expressly provided for in this Agreement.
4. Termination for Infringement.  Either party may terminate this Agreement immediately should any Software become, or in either party's opinion be likely to become, the subject of a claim of infringement of any intellectual property right.
For inquiries please contact: BEA Systems, Inc., 2315 North First Street, San Jose, CA 95131.

252
LICENSE.txt Normal file
View File

@ -0,0 +1,252 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed 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.
============================================
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 Normal file
View File

@ -0,0 +1,34 @@
=========================================================================
== 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 Normal file
View File

@ -0,0 +1,21 @@
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.

50
ant/axis-import.xml Normal file
View File

@ -0,0 +1,50 @@
<?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 name="Beehive/SVN/AxisImports" default="" basedir=".">
<import file="../beehive-imports.xml"/>
<path id="webservice.classpath">
<fileset id="webservice.jars" dir="${beehive.home}/external/axis-1.3">
<include name="axis.jar"/>
<include name="axis-ant.jar"/>
<include name="axis-schema.jar"/>
<include name="jaxrpc.jar"/>
<include name="saaj.jar"/>
<include name="wsdl4j-1.5.1.jar"/>
</fileset>
<path refid="commons-discovery.dependency.path"/>
<path refid="commons-logging.dependency.path"/>
</path>
<macrodef name="deploy-webservice-runtime">
<attribute name="appdir"/>
<sequential>
<copy todir="@{appdir}" failOnError="true">
<fileset refid="webservice.jars"/>
<fileset refid="commons-discovery.fileset"/>
<fileset refid="commons-logging.fileset"/>
</copy>
</sequential>
</macrodef>
</project>

45
ant/beehive-runtime.xml Normal file
View File

@ -0,0 +1,45 @@
<?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 name="Beehive/SVN/DeployWebappRuntime" default="usage" basedir=".">
<import file="../beehive-imports.xml"/>
<!-- ================================================================ -->
<!-- -->
<!-- Targets for deploying the Beehive runtime into a web application -->
<!-- -->
<!-- ================================================================ -->
<!-- params (location webapp.dir) -->
<target name="deploy.beehive.webapp.runtime" description="Deploy the Beehive webapp runtime given a webapp root as -Dwebapp.dir">
<ant target="deploy.netui" dir="${beehive.home}/netui/" inheritAll="false">
<property name="webapp.dir" location="${webapp.dir}"/>
</ant>
</target>
<target name="deploy.controls.webapp.runtime" description="Deploy the Beehive controls runtime given a webapp root as -Dwebapp.dir">
<ant target="deploy.controls.runtime" dir="${beehive.home}/controls/" inheritAll="false">
<property name="webapp.dir" location="${webapp.dir}"/>
</ant>
</target>
</project>

166
ant/beehive-tools.xml Normal file
View File

@ -0,0 +1,166 @@
<?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:$
-->
<!--
This Ant build file contains <macrodef>s that are used to build
Beehive-related source artifacts.
-->
<project name="Beehive/Tools" default="usage">
<path id="apt.task.classpath">
<path refid="controls.dependency.path"/>
<path refid="velocity.dependency.path"/>
</path>
<macrodef name="build-schemas">
<attribute name="srcdir" description="The directory containing XML Schemas or XMLBeans xsdconfig files to build"/>
<attribute name="destdir" description="The directory to use for files generated during an XSD build"/>
<sequential>
<taskdef name="xmlbeanbuild"
classname="org.apache.xmlbeans.impl.tool.XMLBean"
classpathref="xbean.dependency.path"/>
<xmlbeanbuild classpathref="xbean.dependency.path"
schema="@{srcdir}"
classgendir="@{destdir}"
failonerror="true"/>
</sequential>
</macrodef>
<macrodef name="build-controls">
<attribute name="srcdir" description="The directory containing controls to build. Required."/>
<attribute name="destdir" description="The destination directory for compiled class files. Required."/>
<attribute name="tempdir" description="The temporary directory for generated files. Required."/>
<attribute name="classpathref" description="The classpath reference for building the controls. Required."/>
<attribute name="nocompile" default="false" description="Flag to decide whether to skip compilation. Optional; defaults to false"/>
<sequential>
<taskdef name="apt"
classname="org.apache.beehive.controls.runtime.generator.AptTask"
classpathref="apt.task.classpath"
onerror="fail"/>
<!--
since Velocity is required at build time for controls, it needs to be
explicitly added here via the velocity.dependency.path
-->
<path id="_controls.build.classpath">
<path refid="@{classpathref}"/>
<path refid="velocity.dependency.path"/>
</path>
<apt srcdir="@{srcdir}"
destdir="@{destdir}"
gendir="@{tempdir}"
classpathref="_controls.build.classpath"
compileByExtension="true"
srcExtensions="*.java,*.jcx,*.jcs,*.jws"
debug="true"
nocompile="@{nocompile}"/>
</sequential>
</macrodef>
<!--
This macrodef is intended for the compilation of the *page flow* portions of a web application.
This macrodef will *not* compile controls inside of a web application. If the web application
contains controls, they should be compiled first using the macrodef "build-controls";
once the compilation of the controls is complete, the page flows within the web app can be compiled
using the macrodef below.
-->
<macrodef name="build-pageflows">
<attribute name="srcdir" description="The root directory which will be scanned for source files. Required."/>
<attribute name="classpathref" description="The classpath reference for building page flows. Required."/>
<attribute name="sourcepathref"
default="_pageflow.default.sourcepath"
description="A reference to a path that contains all the source roots. Optional; defaults to a path that contains @{srcdir} and @{srcdir}/WEB-INF/src."/>
<attribute name="webcontentdir"
default="@{srcdir}"
description="The root location for web content (e.g., JSPs, web.xml, etc.). Optional; defaults to @{srcdir}."/>
<attribute name="destdir"
default="@{srcdir}/WEB-INF/classes"
description="The directory for compiled classes and generated resources. Optional; defaults to @{srcdir}/WEB-INF/classes."/>
<attribute name="tempdir"
default="@{srcdir}/WEB-INF/.tmpbeansrc"
description="The directory for any temporary or generated files. Optional; defaults to @{srcdir}/WEB-INF/.tmpbeansrc."/>
<attribute name="nocompile"
default="false"
description="Flag to decide whether to skip compilation. Optional; defaults to false"/>
<sequential>
<taskdef name="apt"
classname="org.apache.beehive.controls.runtime.generator.AptTask"
classpathref="apt.task.classpath"
onerror="fail"/>
<!--
since the annotation processor for JPFs isn't contained inside of the JPF runtime
JAR, it needs to be explicitly added here via the netui-compiler.dependency.path
-->
<path id="_pageflow.build.classpath">
<path refid="@{classpathref}"/>
<path refid="netui-compiler.dependency.path"/>
<path refid="velocity.dependency.path"/>
</path>
<path id="_pageflow.default.sourcepath">
<pathelement path="@{srcdir}"/>
<pathelement path="@{srcdir}/WEB-INF/src"/>
</path>
<property name="_pageflow.build.classpath" refid="_pageflow.build.classpath"/>
<property name="_pageflow.build.sourcepath" refid="@{sourcepathref}"/>
<echo> srcdir: @{srcdir}</echo>
<echo> classpath: ${_pageflow.build.classpath}</echo>
<echo> sourcepath: ${_pageflow.build.sourcepath}</echo>
<echo> webcontentdir: @{webcontentdir}</echo>
<echo> destdir: @{destdir}</echo>
<echo> tempdir: @{tempdir}</echo>
<mkdir dir="@{destdir}"/>
<apt srcdir="@{srcdir}"
destdir="@{destdir}"
gendir="@{tempdir}"
classpathref="_pageflow.build.classpath"
sourcepathref="@{sourcepathref}"
srcExtensions="*.jpf,*.jpfs,*.app,*.jsfb,*.java"
processorOptions="web.content.root=@{webcontentdir}"
debug="true"
nocompile="@{nocompile}"/>
</sequential>
</macrodef>
<!-- create a jar of a control -->
<taskdef name="control-jar"
classname="org.apache.beehive.controls.runtime.packaging.ControlJarTask"
classpathref="controls.dependency.path" onerror="report" />
<target name="usage" description="Print the usage for this Ant build file.">
<echo>
The beehive-tools.xml file contains Ant macros which can be used
to build Beehive related source artifacts such as Controls, Page Flows,
and XML Schemas. For examples of how to use these macros, see the
Beehive samples.
Note, this build file does not contain targets that can be called
directly on the command line.
</echo>
</target>
</project>

158
ant/geronimo-imports.xml Normal file
View File

@ -0,0 +1,158 @@
<?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 name="Beehive/SVN/GeronimoImports" default="usage" basedir=".">
<property environment="os"/>
<property name="geronimo.home" location="${os.GERONIMO_HOME}"/>
<!-- Properties used to run Geronimo -->
<property name="geronimo.username" value="system"/>
<property name="geronimo.password" value="manager"/>
<target name="deploy" description="Deploy a app to a running Geronimo server">
<fail unless="webapp.dir" message="Can't deploy webapp; the value ${webapp.dir} was unspecified"/>
<property name="_url" value="file://${webapp.dir}"/>
<echo>deploy webapp from ${_url} with context path ${context.path}</echo>
<java fork="true" jar="${geronimo.home}/bin/deployer.jar">
<arg value="--user"/>
<arg value="${geronimo.username}"/>
<arg value="--password"/>
<arg value="${geronimo.password}"/>
<arg value="deploy"/>
<arg value="${webapp.dir}"/>
</java>
<sleep seconds="5"/>
</target>
<target name="undeploy" description="Undeploy an app running on a Geronimo server">
<!-- context path as used here is actually the targetModuleId for the app to undeploy -->
<fail unless="context.path" message="Can't undeploy module; the value ${context.path} was unspecified"/>
<java fork="true" jar="${geronimo.home}/bin/deployer.jar">
<arg value="--user"/>
<arg value="${geronimo.username}"/>
<arg value="--password"/>
<arg value="${geronimo.password}"/>
<arg value="undeploy"/>
<arg value="${context.path}"/>
</java>
</target>
<target name="redeploy" description="Redeploy an app already running on a Geronimo server">
<!-- context path as used here is actually the targetModuleId for the app to redeploy -->
<fail unless="context.path" message="Can't undeploy module; the value ${context.path} was unspecified"/>
<java fork="true" jar="${geronimo.home}/bin/deployer.jar">
<arg value="--user"/>
<arg value="${geronimo.username}"/>
<arg value="--password"/>
<arg value="${geronimo.password}"/>
<arg value="redeploy"/>
<arg value="${context.path}"/>
</java>
<sleep seconds="5"/>
</target>
<target name="start" description="Start a Geronimo instance.">
<condition property="cmdline.options" value="">
<not><isset property="cmdline.options"/></not>
</condition>
<condition property="java.options" value="">
<not><isset property="java.options"/></not>
</condition>
<echo>startup.dir: ${geronimo.home}/bin</echo>
<echo>cmdline.options: ${cmdline.options}</echo>
<echo>java.options: ${java.options}</echo>
<echo>Starting Geronimo</echo>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${geronimo.home}/bin" executable="sh">
<env key="GERONIMO_HOME" value="${geronimo.home}"/>
<arg line="geronimo.sh start ${cmdline.options}"/>
</exec>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${geronimo.home}\bin" executable="cmd.exe">
<env key="GERONIMO_HOME" value="${geronimo.home}"/>
<arg line="geronimo.bat start ${cmdline.options}"/>
</exec>
<echo>Pausing for 30 seconds while geronimo starts....</echo>
<sleep seconds="30"/>
</target>
<target name="start.with.shmem" description="Start a Geronimo instance with shared memory debugging.">
<condition property="cmdline.options" value="">
<not><isset property="cmdline.options"/></not>
</condition>
<condition property="java.options" value="">
<not><isset property="java.options"/></not>
</condition>
<echo>startup.dir: ${geronimo.home}/bin</echo>
<echo>cmdline.options: ${cmdline.options}</echo>
<echo>java.options: ${java.options}</echo>
<echo>Starting Geronimo with jpda</echo>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${geronimo.home}/bin" executable="sh">
<env key="GERONIMO_HOME" value="${geronimo.home}"/>
<arg line="geronimo.sh jpda start ${cmdline.options}"/>
</exec>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${geronimo.home}\bin" executable="cmd.exe">
<env key="GERONIMO_HOME" value="${geronimo.home}"/>
<arg line="geronimo.bat jpda start ${cmdline.options}"/>
</exec>
<echo>Pausing for 30 seconds while geronimo starts....</echo>
<sleep seconds="30"/>
</target>
<target name="stop" description="Stop the Geronimo server.">
<echo>Stop Geronimo in: ${geronimo.home}</echo>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${geronimo.home}\bin" executable="cmd.exe">
<arg value="geronimo.bat"/>
<arg value="stop"/>
<arg value="--force"/>
<arg value="--user"/>
<arg value="${geronimo.username}"/>
<arg value="--password"/>
<arg value="${geronimo.password}"/>
</exec>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${geronimo.home}/bin" executable="sh">
<arg value="geronimo.sh"/>
<arg value="stop"/>
<arg value="--force"/>
<arg value="--user"/>
<arg value="${geronimo.username}"/>
<arg value="--password"/>
<arg value="${geronimo.password}"/>
</exec>
</target>
<target name="usage" description="Print the usage for this build.xml">
<java fork="no" classname="org.apache.tools.ant.Main">
<arg line="-f ${ant.file} -projecthelp"/>
</java>
</target>
</project>

125
ant/jonas-imports.xml Normal file
View File

@ -0,0 +1,125 @@
<?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 name="jonas-imports" default="" basedir=".">
<property environment="os"/>
<property name="jonas.root" location="${os.JONAS_ROOT}"/>
<property name="jonas.deploy.dir" location="${jonas.root}/webapps"/>
<!-- Properties used to run JOnAS -->
<path id="appserver.build.classpath">
<fileset dir="${jonas.root}/lib/catalina/common/lib">
<include name="*.jar"/>
</fileset>
</path>
<target name="deploy" description="Deploy a webapp to a running Jonas server">
<fail unless="context.path" message="Can't deploy webapp; the value ${context.path} was unspecified"/>
<fail unless="webapp.dir" message="Can't deploy webapp; the value ${webapp.dir} was unspecified"/>
<available property="webapp.available" file="${webapp.dir}" type="dir"/>
<fail unless="webapp.available" message="The webapp at ${webapp.dir} does not exist."/>
<echo>deploy webapp from ${webapp.dir} with context path ${context.path}</echo>
<jar destfile="${jonas.deploy.dir}/${context.path}.war"
basedir="${webapp.dir}" />
<echo>deploying via jonas admin</echo>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${jonas.root}\bin\nt" executable="jonas.bat">
<env key="JONAS_ROOT" value="${jonas.root}"/>
<arg line="/c jonas.bat admin -a ${context.path}.war"/>
</exec>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${jonas.root}/bin/unix" executable="sh">
<env key="JONAS_ROOT" value="${jonas.root}"/>
<arg line="jonas admin -a ${context.path}.war"/>
</exec>
</target>
<target name="undeploy" description="Undeploy a webapp running on a Jonas server">
<fail unless="context.path" message="Can't undeploy webapp; the
value ${context.path} was unspecified"/>
<echo>undeploying via jonas admin</echo>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${jonas.root}\bin\nt" executable="jonas.bat">
<env key="JONAS_ROOT" value="${jonas.root}"/>
<arg line="/c jonas.bat admin -r ${context.path}.war"/>
</exec>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${jonas.root}/bin/unix" executable="sh">
<env key="JONAS_ROOT" value="${jonas.root}"/>
<arg line="jonas admin -r ${context.path}.war"/>
</exec>
<delete file="${jonas.deploy.dir}/${context.path}.war" />
</target>
<target name="redeploy" description="Redeploy a webapp already running on a JOnAS server">
<antcall target="undeploy" />
<antcall target="deploy" />
</target>
<target name="start" description="Start a Jonas instance.">
<condition property="cmdline.options" value="">
<not><isset property="cmdline.options"/></not>
</condition>
<condition property="java.options" value="">
<not><isset property="java.options"/></not>
</condition>
<echo>startup.dir: ${jonas.root}</echo>
<echo>cmdline.options: ${cmdline.options}</echo>
<echo>java.options: ${java.options}</echo>
<echo>Start Jonas</echo>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${jonas.root}\bin\nt" executable="jonas.bat">
<env key="JONAS_ROOT" value="${jonas.root}"/>
<env key="JAVA_OPTS" value="${java.options}"/>
<arg line="/c jonas.bat start ${cmdline.options}"/>
</exec>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${jonas.root}/bin/unix" executable="sh">
<env key="JONAS_ROOT" value="${jonas.root}"/>
<env key="JAVA_OPTS" value="${java.options}"/>
<arg line="jonas start ${cmdline.options}"/>
</exec>
</target>
<target name="start.with.shmem" description="Start a JOnAS instance with shared memory debugging.">
<echo>shmem is not an option for JOnAS. starting normally...</echo>
<antcall target="start" />
</target>
<target name="stop" description="Stop the NetUI server">
<echo>Stop Jonas in: ${jonas.root}</echo>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${jonas.root}\bin\nt" executable="jonas.bat">
<env key="JONAS_ROOT" value="${jonas.root}"/>
<arg line="/c jonas.bat stop"/>
</exec>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${jonas.root}/bin/unix" executable="sh">
<env key="JONAS_ROOT" value="${jonas.root}"/>
<arg line="jonas stop"/>
</exec>
</target>
</project>

137
ant/nightly.xml Normal file
View File

@ -0,0 +1,137 @@
<?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:$
-->
<!--
Ant build file used to product Beehive nightlies
-->
<project name="Beehive Nightly Build" default="usage" basedir=".">
<tstamp>
<format property="date" pattern="yyyyMMdd"/>
</tstamp>
<echo>Get SVN revision</echo>
<exec executable="svnversion" dir=".." failifexecutionfails="true" outputproperty="beehive.svn.revision">
<arg value="."/>
</exec>
<property name="ftp.root" value="http://cvs.apache.org/dist/beehive/nightlies"/>
<property name="ftp.dir" value="beehive/${date}"/>
<property name="url" value="${ftp.root}/${ftp.dir}"/>
<property name="beehive.version" value="${date}-svn${beehive.svn.revision}"/>
<import file="../beehive-imports.xml"/>
<echo>Date: ${date}</echo>
<echo>Beehive SVN revision: ${beehive.svn.revision}</echo>
<echo>Beehive distribution name: ${dist.name}</echo>
<echo>FTP URL: ${url}</echo>
<target name="echo" description="Echo the SVN revision and date for debugging"/>
<target name="run" description="Run the entire nightly build, test, and distribution packaging / testing process">
<antcall target="scrub.tomcat"/>
<ant antfile="../build.xml" target="clean" inheritAll="false"/>
<ant antfile="../build.xml" target="deploy" inheritAll="false"/>
<ant antfile="../build.xml" target="drt" inheritAll="false"/>
<java classname="org.apache.tools.ant.Main" fork="true" failOnError="true">
<classpath>
<pathelement path="${java.class.path}"/>
</classpath>
<arg line="-f ../build.xml build.dist -Dbeehive.version=${beehive.version} -Dant.home=${os.ANT_HOME} -emacs"/>
</java>
<java classname="org.apache.tools.ant.Main" fork="true" failOnError="true">
<classpath>
<pathelement path="${java.class.path}"/>
</classpath>
<arg line="-f ../build.xml build.dist.src -Dbeehive.version=${beehive.version} -Dant.home=${os.ANT_HOME} -emacs"/>
</java>
<java classname="org.apache.tools.ant.Main" fork="true" failOnError="true">
<classpath>
<pathelement path="${java.class.path}"/>
</classpath>
<arg line="-f ../build.xml build.dist.lib -Dbeehive.version=${beehive.version} -Dant.home=${os.ANT_HOME} -emacs"/>
</java>
<java classname="org.apache.tools.ant.Main" fork="true" failOnError="true">
<classpath>
<pathelement path="${java.class.path}"/>
</classpath>
<arg line="-f ../build.xml build.dist.archives -Dbeehive.version=${beehive.version} -Dant.home=${os.ANT_HOME} -emacs"/>
</java>
<antcall target="scrub.tomcat"/>
<java classname="org.apache.tools.ant.Main" fork="true" failOnError="true">
<classpath>
<pathelement path="${java.class.path}"/>
</classpath>
<arg line="-f ${beehive.home}/test/dist-test/build.xml build -Ddist.name=${dist.name} -Dant.home=${os.ANT_HOME} -emacs"/>
</java>
<java classname="org.apache.tools.ant.Main" fork="true" failOnError="true">
<classpath>
<pathelement path="${java.class.path}"/>
</classpath>
<arg line="-f ${beehive.home}/test/dist-test/build.xml run -Dbeehive.dist.dir=${beehive.home}/build/dist/${dist.name} -Dbeehive.dist.name=${dist.name} -Dant.home=${os.ANT_HOME} -emacs"/>
</java>
<!-- ftp to Apache -->
<echo></echo>
<echo></echo>
<echo>FTP to Beehive distribution to Apache</echo>
<echo></echo>
<echo></echo>
</target>
<!-- this target is a work in progress for automatically FTPing the archives via sftp to Apache -->
<target name="sftp.nightly" description="SFTP the nightly release to apache.org; note, this target currently does not work">
<fail unless="user" message="Username undefined"/>
<property name="sftp.script" location="${beehive.home}/build/dist/archives/sftp-${date}-${beehive.svn.revision}"/>
<echo file="${sftp.script}">
chdir /www/cvs.apache.org/dist/beehive/nightlies/
mkdir ${date}
put /home/eko/dev/oss/beehive-nightly/trunk/build/dist/archives/apache-beehive-${date}-${beehive.svn.revision}.tar.gz
put /home/eko/dev/oss/beehive-nightly/trunk/build/dist/archives/apache-beehive-${date}-${beehive.svn.revision}.zip
put /home/eko/dev/oss/beehive-nightly/trunk/build/dist/archives/README.txt
</echo>
<exec dir="." executable="sftp" os="Linux" output="results.txt">
<arg line=" -b ${sftp.script} ${user}@cvs.apache.org"/>
</exec>
</target>
<target name="scrub.tomcat" description="Scrub a local Tomcat install of Beehive related test web applications">
<delete dir="${os.CATALINA_HOME}/work/Catalina/localhost/coreWeb"/>
<delete file="${os.CATALINA_HOME}/conf/Catalina/localhost/coreWeb.xml"/>
<delete dir="${os.CATALINA_HOME}/work/Catalina/localhost/controlsWeb"/>
<delete file="${os.CATALINA_HOME}/conf/Catalina/localhost/controlsWeb.xml"/>
<delete dir="${os.CATALINA_HOME}/work/Catalina/localhost/jsfWeb"/>
<delete file="${os.CATALINA_HOME}/conf/Catalina/localhost/jsfWeb.xml"/>
<delete dir="${os.CATALINA_HOME}/work/Catalina/localhost/urlTemplates"/>
<delete file="${os.CATALINA_HOME}/conf/Catalina/localhost/urlTemplates.xml"/>
</target>
</project>

140
ant/tomcat-imports.xml Normal file
View File

@ -0,0 +1,140 @@
<?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 name="Beehive/SVN/TomcatImports" default="usage" basedir=".">
<property environment="os"/>
<property name="tomcat.home" location="${os.CATALINA_HOME}"/>
<!-- Properties used to run Tomcat -->
<!--
In the long run, there probably needs to be a tomcat.properties file that is imported here
which defines the username / password / port number so that they can be overridden
in a user's environment
-->
<property name="catalina.username" value="manager"/>
<property name="catalina.password" value="manager"/>
<property name="catalina-ant.jar" location="${tomcat.home}/server/lib/catalina-ant.jar"/>
<path id="appserver.build.classpath">
<fileset dir="${tomcat.home}/common/lib">
<include name="*.jar"/>
</fileset>
</path>
<target name="deploy" description="Deploy a webapp to a running Tomcat server">
<fail unless="context.path" message="Can't deploy webapp; the value ${context.path} was unspecified"/>
<fail unless="webapp.dir" message="Can't deploy webapp; the value ${webapp.dir} was unspecified"/>
<available property="webapp.available" file="${webapp.dir}" type="dir"/>
<fail unless="webapp.available" message="The webapp at ${webapp.dir} does not exist."/>
<property name="_url" value="file://${webapp.dir}"/>
<echo>deploy webapp from ${_url} with context path ${context.path}</echo>
<taskdef name="tomcatdeploy" classname="org.apache.catalina.ant.DeployTask" classpath="${catalina-ant.jar}"/>
<tomcatdeploy path="/${context.path}" localWar="${_url}" username="${catalina.username}" password="${catalina.password}"/>
<!-- The Tomcat deploy task doesn't necessarily finish deploying the app when the task completes. Sleep for a few... -->
<sleep seconds="5"/>
</target>
<target name="undeploy" description="Undeploy a webapp running on a Tomcat server">
<fail unless="context.path" message="Can't undeploy webapp; the value ${context.path} was unspecified"/>
<taskdef name="tomcatundeploy" classname="org.apache.catalina.ant.UndeployTask" classpath="${catalina-ant.jar}"/>
<tomcatundeploy path="/${context.path}" username="${catalina.username}" password="${catalina.password}"/>
</target>
<target name="redeploy" description="Redeploy a webapp already running on a Tomcat server">
<fail unless="context.path" message="Can't undeploy webapp; the value ${context.path} was unspecified"/>
<taskdef name="tomcatreload" classname="org.apache.catalina.ant.ReloadTask" classpath="${catalina-ant.jar}"/>
<tomcatreload path="/${context.path}" username="${catalina.username}" password="${catalina.password}"/>
<!-- The Tomcat deploy task doesn't necessarily finish deploying the app when the task completes. Sleep for a few... -->
<sleep seconds="5"/>
</target>
<target name="start" description="Start a Tomcat instance.">
<condition property="cmdline.options" value="">
<not><isset property="cmdline.options"/></not>
</condition>
<condition property="java.options" value="">
<not><isset property="java.options"/></not>
</condition>
<echo>startup.dir: ${tomcat.home}/bin</echo>
<echo>cmdline.options: ${cmdline.options}</echo>
<echo>java.options: ${java.options}</echo>
<echo>Start Tomcat</echo>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${tomcat.home}\bin" executable="cmd.exe">
<env key="JAVA_OPTS" value="${java.options}"/>
<arg line="/c startup.bat ${cmdline.options}"/>
</exec>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${tomcat.home}/bin" executable="sh">
<env key="JAVA_OPTS" value="${java.options}"/>
<arg line="startup.sh ${cmdline.options}"/>
</exec>
</target>
<target name="start.with.shmem" description="Start a Tomcat instance with shared memory debugging.">
<condition property="cmdline.options" value="">
<not><isset property="cmdline.options"/></not>
</condition>
<condition property="java.options" value="">
<not><isset property="java.options"/></not>
</condition>
<echo>startup.dir: ${tomcat.home}/bin</echo>
<echo>cmdline.options: ${cmdline.options}</echo>
<echo>java.options: ${java.options}</echo>
<echo>Start Tomcat</echo>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${tomcat.home}\bin" executable="cmd.exe">
<env key="JAVA_OPTS" value="${java.options}"/>
<arg line="/c catalina.bat jpda start ${cmdline.options}"/>
</exec>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${tomcat.home}/bin" executable="sh">
<env key="JAVA_OPTS" value="${java.options}"/>
<arg line="startup.sh jpda start ${cmdline.options}"/>
</exec>
</target>
<target name="stop" description="Stop the NetUI server">
<echo>Stop Tomcat in: ${tomcat.home}</echo>
<exec os="Windows 2000,Windows 2003,Windows XP" dir="${tomcat.home}\bin" executable="cmd.exe">
<arg line=" /c shutdown"/>
</exec>
<exec os="Linux,SunOS,Solaris,Mac OS X" dir="${tomcat.home}/bin" executable="sh">
<arg line="shutdown.sh"/>
</exec>
</target>
<target name="usage" description="Print the usage for this build.xml">
<java fork="no" classname="org.apache.tools.ant.Main">
<arg line="-f ${ant.file} -projecthelp"/>
</java>
</target>
</project>

374
beehive-imports.xml Normal file
View File

@ -0,0 +1,374 @@
<?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:$
-->
<!--
A build file that needs to be imported by all sub-projects.
-->
<project name="beehive-imports" default="" basedir=".">
<property environment="os"/>
<dirname property="beehive.home" file="${ant.file.beehive-imports}"/>
<property name="ant.dir" location="${os.ANT_HOME}"/>
<property name="forrest.dir" location="${os.FORREST_HOME}"/>
<property name="beehive.version" value="1.0.2"/>
<property name="dist.base.name" value="apache-beehive-"/>
<property name="dist.name" value="${dist.base.name}${beehive.version}"/>
<property name="webservice.runtime" value="axis"/>
<property name="servlet.runtime" value="tomcat"/>
<property name="maven.groupId" value="org/apache/beehive"/>
<property name="build.m2.dir" value="${beehive.home}/build/maven/m2/${maven.groupId}"/>
<property name="build.m1.dir" value="${beehive.home}/build/maven/m1/beehive"/>
<!-- TODO: move the MyFaces jars up into trunk/external -->
<property name="myfaces.dir" location="${beehive.home}/netui/external/jsf/myfaces-1.0.9/lib"/>
<!-- ======================================================================== -->
<!-- Common Beehive paths -->
<!-- ======================================================================== -->
<fileset id="controls.fileset" file="${beehive.home}/controls/build/jars/beehive-controls.jar"/>
<fileset id="system-controls.fileset" dir="${beehive.home}/system-controls/build/jars">
<include name="beehive-jdbc-control.jar"/>
<include name="beehive-jms-control.jar"/>
<include name="beehive-ejb-control.jar"/>
</fileset>
<fileset id="velocity.fileset" dir="${beehive.home}/external/velocity">
<include name="velocity-dep-1.4.jar"/>
</fileset>
<fileset id="commons-codec.fileset" file="${beehive.home}/external/commons/commons-codec-1.3.jar"/>
<fileset id="commons-discovery.fileset" file="${beehive.home}/external/commons/commons-discovery-0.2.jar"/>
<fileset id="derby.fileset" file="${beehive.home}/external/derby/derby_46005.jar"/>
<!-- create a patternset for commons-logging so we can refer to the filename of the jar -->
<patternset id="commons-logging.patternset">
<include name="commons-logging-1.0.4.jar" />
</patternset>
<fileset id="commons-logging.fileset" dir="${beehive.home}/external/commons">
<patternset refid="commons-logging.patternset" />
</fileset>
<fileset id="log4j.fileset" file="${beehive.home}/external/log4j/log4j-1.2.8.jar"/>
<fileset id="xbean.fileset" file="${beehive.home}/external/xmlbeans/apache-xbean.jar"/>
<fileset id="jsr173.fileset" file="${beehive.home}/installed/jsr173/jsr173_1.0_api.jar"/>
<path id="controls.dependency.path">
<pathelement location="${beehive.home}/controls/build/jars/beehive-controls.jar"/>
</path>
<path id="netui-compiler.dependency.path">
<pathelement location="${beehive.home}/netui/build/jars/beehive-netui-compiler.jar"/>
</path>
<path id="velocity.dependency.path">
<fileset refid="velocity.fileset"/>
</path>
<path id="xbean.dependency.path">
<fileset refid="xbean.fileset"/>
<fileset refid="jsr173.fileset"/>
</path>
<path id="commons-codec.dependency.path">
<fileset refid="commons-codec.fileset"/>
</path>
<path id="commons-discovery.dependency.path">
<fileset refid="commons-discovery.fileset"/>
</path>
<path id="derby.dependency.path">
<fileset refid="derby.fileset"/>
</path>
<path id="commons-logging.dependency.path">
<fileset refid="commons-logging.fileset"/>
</path>
<path id="log4j.dependency.path">
<fileset refid="log4j.fileset"/>
</path>
<path id="servlet.dependency.path">
<pathelement location="${beehive.home}/external/servlet/servlet-api-2.4.jar"/>
<pathelement location="${beehive.home}/external/servlet/jsp-api-2.0.jar"/>
</path>
<path id="tools.dependency.path">
<pathelement location="${os.JAVA_HOME}/lib/tools.jar"/>
</path>
<path id="ant-all.dependency.path">
<fileset dir="${ant.home}/lib">
<include name="*.jar"/>
</fileset>
</path>
<path id="ant-jar.dependency.path">
<fileset file="${ant.home}/lib/ant.jar"/>
</path>
<!-- test classpaths-->
<path id="junit.dependency.path">
<pathelement location="${beehive.home}/external/junit/junit.jar"/>
</path>
<!-- controls test classpaths; these should move down into the controls/test/external directory -->
<path id="regexp.dependency.path">
<pathelement location="${beehive.home}/external/jakarta/jakarta-regexp-1.2.jar"/>
</path>
<path id="httpunit.dependency.path">
<pathelement location="${beehive.home}/external/httpunit/httpunit.jar"/>
<pathelement location="${beehive.home}/external/httpunit/nekohtml.jar"/>
<pathelement location="${beehive.home}/external/httpunit/xercesImpl.jar"/>
</path>
<path id="beehive-antext.dependency.path">
<pathelement location="${beehive.home}/external/beehive-antext/beehive-antext.jar"/>
</path>
<!-- ======================================================================== -->
<!-- Common Beehive Ant macros -->
<!-- ======================================================================== -->
<macrodef name="copy-junit">
<attribute name="todir"/>
<sequential>
<copy todir="@{todir}">
<fileset file="${beehive.home}/external/junit/junit.jar"/>
</copy>
</sequential>
</macrodef>
<macrodef name="copy-log4j">
<attribute name="todir"/>
<sequential>
<copy todir="@{todir}">
<fileset refid="log4j.fileset"/>
</copy>
</sequential>
</macrodef>
<macrodef name="copy-xbean">
<attribute name="todir"/>
<sequential>
<copy todir="@{todir}">
<fileset refid="xbean.fileset"/>
</copy>
</sequential>
</macrodef>
<macrodef name="copy-controls">
<attribute name="todir"/>
<sequential>
<copy todir="@{todir}">
<fileset refid="controls.fileset"/>
<fileset refid="velocity.fileset"/>
<fileset refid="commons-discovery.fileset"/>
</copy>
</sequential>
</macrodef>
<macrodef name="deploy-netui">
<attribute name="webappDir"/>
<sequential>
<echo>Deploy NetUI to webapp @{webappDir}</echo>
<ant dir="${beehive.home}/ant/" antfile="beehive-runtime.xml" target="deploy.beehive.webapp.runtime" inheritAll="false">
<property name="webapp.dir" location="@{webappDir}"/>
</ant>
</sequential>
</macrodef>
<macrodef name="deploy-controls">
<attribute name="destDir"/>
<sequential>
<echo>Deploy Controls to directory @{destDir}</echo>
<ant dir="${beehive.home}/ant" antfile="beehive-runtime.xml" target="deploy.controls.webapp.runtime" inheritAll="false">
<property name="dest.dir" location="@{destDir}"/>
</ant>
</sequential>
</macrodef>
<macrodef name="deploy-webapp">
<attribute name="webappDir"/>
<attribute name="contextPath"/>
<sequential>
<ant dir="${beehive.home}/ant" antfile="${servlet.runtime}-imports.xml" target="deploy" inheritAll="false">
<property name="webapp.dir" location="@{webappDir}"/>
<property name="context.path" value="@{contextPath}"/>
</ant>
</sequential>
</macrodef>
<macrodef name="undeploy-webapp">
<attribute name="contextPath"/>
<sequential>
<ant dir="${beehive.home}/ant" antfile="${servlet.runtime}-imports.xml" target="undeploy" inheritAll="false">
<property name="context.path" value="@{contextPath}"/>
</ant>
</sequential>
</macrodef>
<macrodef name="redeploy-webapp">
<attribute name="contextPath"/>
<sequential>
<ant dir="${beehive.home}/ant" antfile="${servlet.runtime}-imports.xml" target="redeploy" inheritAll="false">
<property name="context.path" value="@{contextPath}"/>
</ant>
</sequential>
</macrodef>
<macrodef name="start-server">
<attribute name="shmem"/>
<attribute name="javaOptions"/>
<sequential>
<!-- if shmem, set target to "start.shmem" -->
<condition property="start.target" value="start.with.shmem">
<istrue value="@{shmem}"/>
</condition>
<condition property="start.target" value="start">
<isfalse value="@{shmem}"/>
</condition>
<ant dir="${beehive.home}/ant" antfile="${servlet.runtime}-imports.xml" target="${start.target}" inheritAll="false">
<property name="java.options" value="@{javaOptions}"/>
</ant>
</sequential>
</macrodef>
<macrodef name="stop-server">
<sequential>
<ant dir="${beehive.home}/ant" antfile="${servlet.runtime}-imports.xml" target="stop" inheritAll="false"/>
</sequential>
</macrodef>
<macrodef name="build-xbean">
<attribute name="schemaDir"/>
<attribute name="classgenDir"/>
<attribute name="source" default="1.5"/>
<attribute name="xbeanBuildClasspathRef" default="xbean.dependency.path"/>
<sequential>
<property name="curr.classpath" refid="@{xbeanBuildClasspathRef}"/>
<echo>XMLBean build classpath: ${curr.classpath}</echo>
<taskdef name="xmlbeanbuild"
classname="org.apache.xmlbeans.impl.tool.XMLBean"
classpathref="xbean.dependency.path"/>
<xmlbeanbuild
schema="@{schemaDir}"
classgendir="@{classgenDir}"
failonerror="true"
source="@{source}"
classpathref="@{xbeanBuildClasspathRef}"/>
</sequential>
</macrodef>
<!-- ======================================================================== -->
<!-- Common Beehive tasks -->
<!-- ======================================================================== -->
<taskdef name="gethostname"
classname="org.apache.beehive.test.tools.antext.GetHostName"
classpathref="beehive-antext.dependency.path"/>
<!-- ======================================================================== -->
<!-- Verify JDK version -->
<!-- ======================================================================== -->
<property name="required.jdk.version" value="1.5"/>
<condition property="jdk.version.okay">
<contains string="${java.version}" substring="${required.jdk.version}"/>
</condition>
<fail unless="jdk.version.okay">
Newer JDK required.
Building the project requires JDK ${required.jdk.version}
You are currently using the following JDK:
java.home = ${java.home}
java.version = ${java.version}
java.vendor = ${java.vendor}
You may obtain a newer version of the JDK from
http://java.sun.com/
If you have JDK ${required.jdk.version} installed on your system, you may need to
adjust your JAVA_HOME environment variable.
</fail>
<!-- ======================================================================== -->
<!-- Verify ANT version -->
<!-- ======================================================================== -->
<condition property="ant.version.okay">
<or>
<!-- allow ant 1.7 for gump runs -->
<contains string="${ant.version}" substring="1.6"/>
<contains string="${ant.version}" substring="1.7"/>
</or>
</condition>
<fail unless="ant.version.okay">
Newer Ant required.
Building the project required Apache Ant 1.6.
You are currently using the following apache-ant:
ant.home = ${ant.home}
ant.version = ${ant.version}
You may obtain a newer version of ant from
http://ant.apache.org/
If you have Ant 1.6 installed on your system, you may need to
adjust your ANT_HOME environment variable.
</fail>
<mkdir dir="${beehive.home}/build/lib/"/>
<!-- ======================================================================== -->
<!-- Common targets -->
<!-- ======================================================================== -->
<target name="usage" description="Print the usage for this build.xml">
<java fork="no" classname="org.apache.tools.ant.Main">
<arg line="-f ${ant.file} -projecthelp"/>
</java>
</target>
</project>

321
build.xml Normal file
View File

@ -0,0 +1,321 @@
<?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 name="Beehive/Main" default="usage" basedir=".">
<import file="beehive-imports.xml"/>
<!-- Local properties used to specify the installers and the directories into which they should be installed -->
<property name="beehive.installed.dir" location="${beehive.home}/installed"/>
<property name="jsr173-bundle.name" value="jsr173_1.0_api_bundle.jar"/>
<property name="jsr173.jar" location="${beehive.home}/installed/jsr173/jsr173_1.0_api.jar"/>
<target name="bootstrap" depends="ensure.proxysettings" description="Install external dependencies to the installed/ directory">
<antcall target="install.deps"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- Build targets -->
<!-- -->
<!-- ============================================= -->
<target name="clean" description="Clean Beehive">
<ant dir="controls" target="clean" inheritAll="false"/>
<ant dir="netui" target="clean" inheritAll="false"/>
<ant dir="system-controls" target="clean" inheritAll="false"/>
<ant dir="docs" target="clean" inheritAll="false"/>
<delete dir="${beehive.home}/build"/>
<!-- remove the old controlhaus/ directory used pre Beehive 1.0 to sync
the system controls from http://svn.controlhaus.org.
eventually, we should remove this step.
-->
<delete dir="${beehive.home}/controlhaus" quiet="true" failonerror="false"/>
</target>
<target name="deploy" description="Deploy Beehive" depends="revision.label">
<ant dir="controls" target="build" inheritAll="false"/>
<ant dir="netui" target="deploy" inheritAll="false"/>
<ant dir="system-controls" target="build" inheritAll="false"/>
</target>
<target name="build.samples" description="Build the Beehive samples">
<ant antfile="samples/build.xml" target="build" inheritAll="false"/>
</target>
<target name="clean.samples" description="Clean the Beehive samples">
<ant antfile="samples/build.xml" target="clean" inheritAll="false"/>
</target>
<target name="revision.label" unless="no.network" description="Creates svn revision label file">
<mkdir dir="${beehive.home}/build"/>
<exec executable="svnversion" outputproperty="svn.revision" failifexecutionfails="false">
<arg value="."/>
</exec>
<echo message="Apache Beehive svn revision #${svn.revision}" file="${beehive.home}/build/svn.rev"/>
</target>
<target name="scrub" description="Scrub the Beehive directory of downloaded files">
<delete dir="installed"/>
<antcall target="clean"/>
<antcall target="clean.samples"/>
</target>
<target name="maven2.install" description="Install the Beehive resources in the Maven repository">
<ant dir="maven" target="clean.m2" inheritAll="false"/>
<ant dir="maven" target="build.m2" inheritAll="false"/>
<ant dir="maven" target="install.m2" inheritAll="false"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- Test targets -->
<!-- -->
<!-- ============================================= -->
<target name="drt" description="Run the Beehive DRT suite">
<antcall target="controls.drt"/>
<antcall target="netui.drt"/>
<antcall target="systemcontrols.drt"/>
</target>
<target name="controls.drt" description="Run the Beehive/Controls DRT suite">
<ant dir="controls" target="drt" inheritAll="false"/>
</target>
<target name="netui.drt" description="Run the Beehive/NetUI DRT suite">
<ant dir="netui" antfile="build.xml" target="drt" inheritAll="false"/>
</target>
<target name="systemcontrols.drt" description="Run the Beehive/System Controls DRT suite">
<ant dir="system-controls" antfile="build.xml" target="drt" inheritAll="false"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- Installation targets. These are used to -->
<!-- install external products that Beehive -->
<!-- depends on to build or test. -->
<!-- -->
<!-- ============================================= -->
<target name="install.deps" description="Ensure that any external dependencies have been installed locally">
<antcall target="ensure.jsr173"/>
</target>
<target name="uninstall.deps" description="Uninstall the external dependencies">
<delete dir="${beehive.installed.dir}"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- JSR 173 == this is required by XMLBeans and -->
<!-- needs to be downloaded from the net. -->
<!-- -->
<!-- ============================================= -->
<target name="ensure.jsr173">
<available file="${jsr173.jar}" type="file" property="jsr173.present"/>
<antcall target="get.jsr173"/>
</target>
<target name="get.jsr173" unless="jsr173.present">
<property name="jsr173.installer" location="${beehive.home}/external/xmlbeans/${jsr173-bundle.name}"/>
<echo>JSR 173 API JAR not found in directory: ${beehive.installed.dir}</echo>
<get dest="${jsr173.installer}"
src="http://www.ibiblio.org/maven/xmlbeans/jars/${jsr173-bundle.name}"
verbose="true"
usetimestamp="true"
ignoreerrors="false"/>
<unzip src="${jsr173.installer}" dest="${beehive.installed.dir}/jsr173"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- Proxy Setup Targets. -->
<!-- -->
<!-- These settings are used if a proxy needs to -->
<!-- be used when downloading third party software -->
<!-- on which Beehive depends. See BUILDING.txt -->
<!-- for more information. -->
<!-- -->
<!-- ============================================= -->
<target name="ensure.proxysettings">
<echo>Check to see if proxy setup is required</echo>
<condition property="proxy.needed">
<and>
<isset property="os.PROXYHOST"/>
</and>
</condition>
<condition property="socks.proxy.needed" value="true">
<and>
<isset property="os.SOCKSPROXYHOST"/>
</and>
</condition>
<antcall target="set.proxy"/>
<antcall target="set.socks.proxy"/>
</target>
<target name="set.proxy" if="proxy.needed">
<echo>Proxy setup needed.</echo>
<echo>Proxy host: ${os.PROXYHOST}</echo>
<echo>Proxy port: ${os.PROXYPORT}</echo>
<echo>Proxy user: ${os.PROXYUSER}</echo>
<echo>Proxy password: ${os.PROXYPASSWORD}</echo>
<echo>Non proxy hosts: ${os.NONPROXYHOSTS}</echo>
<setproxy proxyhost="${os.PROXYHOST}"
proxyport="${os.PROXYPORT}"
proxyuser="${os.PROXYUSER}"
proxypassword="${os.PROXYPASSWORD}"
nonproxyhosts="${os.NONPROXYHOSTS}"/>
</target>
<target name="set.socks.proxy" if="socks.proxy.needed">
<echo>Socks Proxy setup needed.</echo>
<setproxy socksproxyhost="${os.SOCKSPROXYHOST}" socksproxyport="${os.SOCKSPROXYPORT}"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- Documentation targets -->
<!-- -->
<!-- ============================================= -->
<target name="docs" description="Generate the Beehive documentation">
<echo>Ensuring Forrest present in directory: ${forrest.dir}</echo>
<available file="${forrest.dir}" type="dir" property="forrest.present"/>
<fail unless="forrest.present" message="You must have Apache Forrest installed to execute this target. For more information, see trunk/BUILDING.TXT"/>
<ant dir="docs" target="build.release"/>
<ant dir="controls" target="docs" inheritAll="false"/>
<ant dir="netui" target="docs" inheritAll="false"/>
<ant dir="system-controls" target="docs" inheritAll="false"/>
</target>
<target name="build.release.docs" description="Build the documentation for the release represented by this source root">
<ant antfile="distribution.xml" target="build.release.docs"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- Distribution targets -->
<!-- -->
<!-- ============================================= -->
<target name="clean.dist" description="Clean the Beehive distribution directories">
<ant antfile="distribution.xml" target="clean.dist" inheritAll="false"/>
</target>
<target name="build.dist" description="Build the Beehive Binary distribution directory">
<ant antfile="distribution.xml" target="build.dist" inheritAll="false"/>
</target>
<target name="build.dist.lib" description="Build the Beehive Library distribution directory">
<ant antfile="distribution.xml" target="build.dist.lib" inheritAll="false"/>
</target>
<target name="build.dist.src" description="Build the Beehive Source distribution directory">
<ant antfile="distribution.xml" target="build.dist.src" inheritAll="false"/>
</target>
<target name="build.dist.archives" description="Create all Beehive distribution archives">
<ant antfile="distribution.xml" target="build.dist.archives" inheritAll="false"/>
</target>
<target name="build.dist.full" description="Cleans/Builds/Bundles the full Beehive distribution archives (does not run tests though).">
<antcall target="clean"/>
<antcall target="deploy"/>
<antcall target="build.dist"/>
<antcall target="build.dist.lib"/>
<antcall target="build.dist.src"/>
<antcall target="build.dist.archives"/>
</target>
<target name="rat" description="Run RAT on the distribution packages">
<ant antfile="distribution.xml" target="rat" inheritAll="false"/>
</target>
<!-- consider getting rid of this one too, since run.test.dist does this too -->
<target name="build.test.dist" description="Build the Beehive Distribution Tests">
<ant antfile="distribution.xml" target="build.test.dist" inheritAll="false"/>
</target>
<target name="run.test.dist" description="Run the Beehive Distribution Tests against the distribution archives">
<ant antfile="distribution.xml" target="run.test.dist" inheritAll="false"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- Distribution targets -->
<!-- -->
<!-- ============================================= -->
<target name="create.web.project" description="Create a Beehive-enabled web project">
<fail unless="webapp.dir" message="The ${webapp.dir} property is unset"/>
<mkdir dir="${webapp.dir}"/>
</target>
<!-- ============================================= -->
<!-- -->
<!-- Environment sanity check. Use this if you -->
<!-- experience problems running Beehive build -->
<!-- or tests. -->
<!-- -->
<!-- ============================================= -->
<target name="check.setup" description="Verifies that you have the prerequisites for building Beehive.">
<echo>
java.home = ${java.home}
ant.home = ${ant.home}
beehive.home = ${beehive.home}
beehive.version = ${beehive.version}
</echo>
<available file="${jsr173.jar}" type="file" property="jsr173.available"/>
<fail unless="jsr173.available" message="The JSR 173 JAR does not appear to be installed. Be sure to run &quot;ant bootstrap&quot;."/>
<echo>JSR 173 is installed correctly as ${jsr173.jar}</echo>
<!-- check to see if the JUnit classes are available -->
<available classname="junit.framework.TestCase" property="junit.available"/>
<fail unless="junit.available"
message="The classes in junit.jar do not seem to be available. Please ensure junit.jar is available in ${os.ANT_home}/lib"/>
<echo>junit.jar appears to be available since the class "junit.framework.TestCase" was successfully loaded</echo>
<!-- note, to ease the transition when removing Tomcat from the build, this will check a hard reference to CATALINA_HOME -->
<available file="${os.CATALINA_HOME}" type="dir" property="tomcat.available"/>
<fail unless="tomcat.available"
message="The directory ${os.CATALINA_HOME} does not appear to be available. Please define CATALINA_HOME"/>
<echo>Tomcat appears to be available in ${os.CATALINA_HOME}</echo>
<!-- note, to ease the transition when removing Tomcat from the build, this will check a hard reference to CATALINA_HOME -->
<loadfile srcFile="${os.CATALINA_HOME}/conf/tomcat-users.xml" property="tomcat.users.file" failOnError="true"/>
<condition property="tomcat.manager.defined">
<and>
<contains string="${tomcat.users.file}" substring="rolename=&quot;manager&quot;"/>
<contains string="${tomcat.users.file}" substring="username=&quot;manager&quot;"/>
<contains string="${tomcat.users.file}" substring="password=&quot;manager&quot;"/>
</and>
</condition>
<fail unless="tomcat.manager.defined"
message="The manager role may not be defined in ${os.CATALINA_HOME}/conf/tomcat-users.xml. Please ensure that there is a manager role defined with username/password of manager/manager"/>
<echo>manager role appears to be defined in ${os.CATALINA_HOME}/conf/tomcat-users.xml</echo>
</target>
</project>

98
controls/README.txt Normal file
View File

@ -0,0 +1,98 @@
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).

265
controls/build.xml Normal file
View File

@ -0,0 +1,265 @@
<?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 name="Beehive/Controls" default="usage" basedir=".">
<property environment="os"/>
<import file="../beehive-imports.xml"/>
<property name="build.dir" location="build"/>
<property name="classes.dir" location="${build.dir}/classes"/>
<property name="jars.dir" location="${build.dir}/jars"/>
<property name="docs.dir" location="${build.dir}/docs"/>
<property name="api.dir" location="src/api"/>
<property name="api.classes" location="${classes.dir}/api"/>
<property name="spi.dir" location="src/spi"/>
<property name="runtime.dir" location="src/runtime"/>
<property name="runtime.classes" location="${classes.dir}/runtime"/>
<property name="test-container.dir" location="src/test-container"/>
<property name="test-container.classes" location="${classes.dir}/test-container"/>
<property name="controls.jar" location="${jars.dir}/beehive-controls.jar"/>
<path id="api.classpath">
<path refid="commons-discovery.dependency.path"/>
</path>
<path id="spi.classpath">
<pathelement location="${api.classes}"/>
</path>
<path id="runtime.classpath">
<path refid="ant-all.dependency.path"/>
<path refid="servlet.dependency.path"/>
<path refid="velocity.dependency.path"/>
<path refid="tools.dependency.path"/>
<path refid="api.classpath"/>
<pathelement location="${api.classes}"/>
</path>
<path id="test-container.classpath">
<path refid="junit.dependency.path"/>
<path refid="runtime.classpath"/>
<pathelement location="${runtime.classes}"/>
</path>
<!-- ==================================================================== -->
<!-- usage - output usage -->
<!-- ==================================================================== -->
<target name="usage">
<echo message=""/>
<echo message=""/>
<echo message="Controls Build file"/>
<echo message="================================================================"/>
<echo message="| Usage |"/>
<echo message="================================================================"/>
<echo message=""/>
<echo message="----------------------------------------------------------------"/>
<echo message="| Standard Targets |"/>
<echo message="----------------------------------------------------------------"/>
<echo message="build - build java classes and jar files"/>
<echo message="clean - remove build files"/>
<echo message="deploy - does nothing for this project"/>
<echo message="redeploy - do an &quot;clean&quot;, &quot;, &quot;build&quot; and &quot;deploy&quot;."/>
<echo message="docs - build the java docs"/>
<echo message="drt - runs the DRT (developer regression test)"/>
<echo message=""/>
<echo message="----------------------------------------------------------------"/>
<echo message="| Project-Specific Targets |"/>
<echo message="----------------------------------------------------------------"/>
<echo message="dirs - Creates the output directories of the build."/>
<echo message="classes - Compiles the source code of the project."/>
<echo message="================================================================"/>
<echo message="| NOTE: THE WSM PROJECT ONLY BUILDS ON JDK5 AND LATER |"/>
<echo message="================================================================"/>
<echo message=""/>
<echo message=""/>
</target>
<!-- ==================================================================== -->
<!-- Creates the output directories of the build. -->
<!-- ==================================================================== -->
<target name="dirs">
<mkdir dir="${api.classes}"/>
<mkdir dir="${runtime.classes}"/>
<mkdir dir="${test-container.classes}"/>
<mkdir dir="${jars.dir}"/>
<mkdir dir="${docs.dir}"/>
</target>
<!-- ==================================================================== -->
<!-- Compiles the source code of the project. -->
<!-- ==================================================================== -->
<target name="classes" depends="dirs">
<!-- Build the API and SPI classes -->
<!-- These are built together because there are some cross-depencies -->
<!-- where API classes reference SPI interfaces -->
<javac destdir="${api.classes}" classpathref="api.classpath" debug="on">
<src path="${api.dir}"/>
<src path="${spi.dir}"/>
</javac>
<!-- Build the runtime classes -->
<javac destdir="${runtime.classes}" classpathref="runtime.classpath" debug="on">
<src path="${runtime.dir}"/>
</javac>
<!-- Build the test container classes -->
<javac destdir="${test-container.classes}" classpathref="test-container.classpath" debug="on">
<src path="${test-container.dir}"/>
</javac>
<!-- Copy property files into the build -->
<copy todir="${runtime.classes}" overwrite="true">
<fileset dir="${runtime.dir}" includes="**/*.properties"/>
<fileset dir="${runtime.dir}" includes="**/*.template,**/*.vm,META-INF/**"/>
</copy>
</target>
<!-- ==================================================================== -->
<!-- Jars up the classes, libraries, and resources. -->
<!-- ==================================================================== -->
<target name="build" depends="classes">
<echo message="--------------------------------------------------"/>
<echo message="| controls build starting |"/>
<echo message="--------------------------------------------------"/>
<jar jarfile="${controls.jar}">
<metainf dir="${beehive.home}">
<include name="LICENSE.txt"/>
<include name="NOTICE.txt"/>
</metainf>
<fileset dir="${api.classes}"/>
<fileset dir="${runtime.classes}"/>
<fileset dir="${test-container.classes}"/>
<manifest>
<attribute name="Extension-Name" value="Beehive Controls Runtime"/>
<attribute name="Specification-Title" value="Beehive Controls Runtime"/>
<attribute name="Specification-Vendor" value="Apache Software Foundation"/>
<attribute name="Specification-Version" value="${beehive.version}"/>
<attribute name="Implementation-Title" value="Beehive Controls Runtime"/>
<attribute name="Implementation-Vendor" value="Apache Software Foundation"/>
<attribute name="Implementation-Version" value="${beehive.version}"/>
<attribute name="Beehive-Version" value="${beehive.version}"/>
</manifest>
</jar>
<echo message="--------------------------------------------------"/>
<echo message="| controls build ending |"/>
<echo message="--------------------------------------------------"/>
</target>
<!-- ==================================================================== -->
<!-- clean -->
<!-- ==================================================================== -->
<target name="clean">
<delete dir="${build.dir}"/>
<ant dir="./test" target="clean" inheritAll="false"/>
</target>
<!-- ==================================================================== -->
<!-- deploy -->
<!-- ==================================================================== -->
<target name="deploy" depends="build">
<echo message="--------------------------------------------------"/>
<echo message="| controls deploy starting |"/>
<echo message="--------------------------------------------------"/>
<!-- Copy build output to client locations (lib dir of servers etc) -->
<echo message="--------------------------------------------------"/>
<echo message="| controls deploy ending |"/>
<echo message="--------------------------------------------------"/>
</target>
<!-- ==================================================================== -->
<!-- deploy.controls.runtime -->
<!-- ==================================================================== -->
<target name="deploy.controls.runtime"
description="Deploy the controls runtime to a fully-qualified webapp directory specified with the property 'dest.dir'">
<available property="dir.available" file="${dest.dir}" type="dir"/>
<fail unless="dir.available" message="Can't find the destination directory ${dest.dir}"/>
<echo message="Deploy Controls JARs to ${dest.dir}"/>
<copy todir="${dest.dir}" failOnError="true">
<fileset refid="controls.fileset"/>
<fileset refid="commons-discovery.fileset"/>
</copy>
</target>
<!-- ==================================================================== -->
<!-- docs -->
<!-- ==================================================================== -->
<target name="docs">
<javadoc destdir="${docs.dir}/apidocs/"
maxmemory="256M"
windowtitle="Apache Beehive Controls API Documentation (Version ${beehive.version})"
doctitle="Apache Beehive Controls API Documentation (Version ${beehive.version})"
version="true"
author="false"
use="true"
additionalparam="-breakiterator -noqualifier all -notimestamp"
useexternalfile="true"
classpathref="runtime.classpath">
<packageset dir="${api.dir}" defaultexcludes="yes">
<include name="org/apache/beehive/controls/**/*"/>
</packageset>
<packageset dir="${runtime.dir}" defaultexcludes="yes">
<include name="org/apache/beehive/controls/**/*"/>
</packageset>
<packageset dir="${spi.dir}" defaultexcludes="yes">
<include name="org/apache/beehive/controls/**/*"/>
</packageset>
<packageset dir="${test-container.dir}" defaultexcludes="yes">
<include name="org/apache/beehive/controls/**/*"/>
</packageset>
</javadoc>
<fixcrlf srcDir="${build.dir}/docs/apidocs" includes="**/*.html"/>
</target>
<target name="deploy.m2">
<copy todir="${build.m2.dir}/beehive-controls/${beehive.version}">
<mapper type="glob" from="*.jar" to="*-${beehive.version}.jar"/>
<fileset dir="build/jars">
<include name="beehive-controls.jar"/>
</fileset>
</copy>
<filter token="beehive.version" value="${beehive.version}"/>
<copy todir="${build.m2.dir}/beehive-controls/${beehive.version}" filtering="true">
<mapper type="glob" from="*.pom" to="*-${beehive.version}.pom"/>
<fileset dir="src" includes="beehive-controls.pom"/>
</copy>
<jar destfile="${build.m2.dir}/beehive-controls/${beehive.version}/beehive-controls-${beehive.version}-sources.jar">
<fileset dir="src/api"/>
<fileset dir="src/runtime"/>
<fileset dir="src/spi"/>
<fileset dir="src/test-container"/>
</jar>
</target>
<!-- ==================================================================== -->
<!-- drt -->
<!-- ==================================================================== -->
<target name="drt">
<ant dir="test" target="drt" inheritAll="false"/>
</target>
<target name="bvt">
<ant dir="test" target="bvt" inheritAll="false"/>
</target>
</project>

View File

@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api;
/**
* The ControlException class declares an unchecked exception that is thrown by the Controls
* runtime under certain failure conditions.
*/
public class ControlException extends RuntimeException
{
/**
* Default constructor.
*/
public ControlException() {
super();
}
/**
* Constructs a ControlException object with the specified String as a message.
*
* @param message The message to use.
*/
public ControlException(String message)
{
super(message);
}
/**
* Constructs a ControlException with the specified cause.
* @param t the cause
*/
public ControlException(Throwable t) {
super(t);
}
/**
* Constructs a ControlException object using the specified String as a message, and the
* specified Throwable as a nested exception.
*
* @param message The message to use.
* @param t The exception to nest within this exception.
*/
public ControlException(String message, Throwable t)
{
super(message + "[" + t + "]", t);
}
}

View File

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.assembly;
/**
* Control implementations may need to do build-time work on or impacted by
* their control client(s), such as side-effecting their client's deployment
* descriptors, or generating additional files that are implementation-
* specific.
*
* The build phase where this work is done is called assembly, and occurs
* at the granularity level of the J2EE module.
* The control author participates in this phase by authoring classes that
* implement the ControlAssembler interface, and associating such classes
* with control implementations. Instances of ControlAssembler are then
* called at assembly-time by build tools.
*/
public interface ControlAssembler
{
/**
* A ControlAssembler implementation's assemble method is called once
* per control assembler per module per assembly-time pass. The call
* passes a ControlAssemblyContext, from which information such as the
* list of client classes in the module that use the control can be
* obtained.
*/
void assemble(ControlAssemblyContext cac) throws ControlAssemblyException;
}

View File

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

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.assembly;
/**
* Checked exceptions thrown during the assembly process. ControlAssembler
* implementations may throw this exception in their assemble() method, which
* will halt the assembly process.
*/
public class ControlAssemblyException extends Exception
{
public ControlAssemblyException(String msg)
{
super(msg);
}
public ControlAssemblyException(String msg, Throwable cause)
{
super(msg, cause);
}
}

View File

@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.assembly;
/**
* The default or "empty" control assembler that's assigned to an @ControlImplementation's
* assembler attribute if none is provided.
*/
public final class DefaultControlAssembler implements ControlAssembler
{
public void assemble(ControlAssemblyContext cac) throws ControlAssemblyException { };
}

View File

@ -0,0 +1,90 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Retention;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* AnnotationConstraints defines meta-annotations that allow
* specification of additional constraints that aren't
* expressible using J2SE 5.0 meta-annotations.
*
* Actual enforcement of these semantics is implementation dependent.
* An <code>apt</code>-based reference implementation is provided by
* {@link org.apache.beehive.controls.runtime.bean.AnnotationConstraintValidator}.
*
* @see org.apache.beehive.controls.runtime.bean.AnnotationConstraintValidator
*/
public interface AnnotationConstraints
{
/**
* Defines a number of simple constraints on the way annotation members
* can be used together.
*
* @see MembershipRule
*/
public enum MembershipRuleValues
{
AT_LEAST_ONE,
AT_MOST_ONE,
EXACTLY_ONE,
ALL_IF_ANY
}
/**
* Provides a mechanism for enforcing constraints between members of
* an annotation (such a mechanism is absent from J2SE 5.0; for example,
* given an annotation with members 'a' and 'b' there is no way to say
* that they are mutually exclusive).
*
* @see MembershipRuleValues
*/
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MembershipRule
{
/** Required, the membership rule.*/
MembershipRuleValues value();
/** Optional list of member names to apply rule against. Empty array implies all members. */
String[] memberNames() default {};
}
/**
* Defines whether the annotation decorated by this
* annotation can overriden externally (a marker interface).
*/
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AllowExternalOverride
{
}
/**
* Specifies the version of the control runtime required by this annotation.
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredRuntimeVersion
{
String value(); // no default
}
}

View File

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

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The Control annotation type is used to annotate a field within a control
* client source file that is a control reference. It is the declarative
* mechanism for instantiating controls in Java clients. Java Controls
* runtime implementations will automatically initialize such annotated field
* references to an appropriate Java Control Bean of the requested type,
* and perform event listener hookup etc.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Control
{
/**
* Optional member used to specify the control interface class.
* Typically only necessary to resolve ambiguities when multiple
* control interfaces with same name but different packages are present.
*/
Class<?> interfaceHint() default Object.class;
}

View File

@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.beans.beancontext.BeanContext;
import java.beans.beancontext.BeanContextProxy;
import org.apache.beehive.controls.api.context.ControlBeanContext;
/**
* The ControlBean interface defines a base set of methods that are implemented by all
* <code>JavaBeans</code> that host Java Controls.
* <p>
* A ControlBean will implement the <code>java.beans.beancontext.BeanContextProxy</code>
* interface to provide a way to get the <code>BeanContext</code> directly associated
* with the Java Control. The <code>getBeanContext()</code> API on the interface will
* return the parent (containing) context.
*
* @see java.beans.beancontext.BeanContextProxy
*/
public interface ControlBean extends BeanContextProxy, java.io.Serializable
{
/**
* The IDSeparator character is used to separated individual control IDs in nesting
* scenarios whether the identifier is actually a composite path that represents
* a nesting relationship.
*/
public static final char IDSeparator = '/';
/**
* Returns the <code>java.beans.beancontext.BeanContext</code> that provides the parent
* context for the Java Control.
* @return the containing <code>BeanContext</code> for the Java ControlBean.
*
* @see java.beans.beancontext.BeanContext
*/
BeanContext getBeanContext();
/**
* Returns the <code>org.apache.beehive.controls.api.context.ControlBeanContext</code> instance
* that provides the local context for this control bean. <b>This is not the parent
* context for the control.</b> It is the context that would be the parent context for
* any nested controls hosted by this control.
*/
ControlBeanContext getControlBeanContext();
/**
* Returns the unique control ID associated with the Java ControlBean. This control ID
* is guaranteed to be unique within the containing <code>BeanContext</code>
* @return the control ID
*/
String getControlID();
/**
* Returns the Java Control public interface for the ControlBean. This interface defines
* the operations and events exposed by the Java Control to its clients.
* @return the control public interface
*/
Class getControlInterface();
}

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.Declaration;
/**
* The ControlChecker interface is implemented by control authors wishing to
* enforce rich semantic validation on extension and field instance declarations of
* their controls. By supplying a ControlChecker implementation (a "checker")
* and associating it with your control's public interface, when an extension (.jcx)
* of your control is processed at build-time, the checker will be invoked and
* can do rich validation of the jcx type and field instances via introspection and
* analysis of the jcx's type structure, signatures and annotations.
* <p>
* Checkers are instantiated by, and required to implement, a no-arg constructor.
* They are provided with type information and context via the Sun mirror API.
*/
public interface ControlChecker
{
/**
* Invoked by the control build-time infrastructure to process a declaration of
* a control extension (ie, an interface annotated with @ControlExtension), or
* a field instance of a control type.
*/
public void check(Declaration decl, AnnotationProcessorEnvironment env);
}

View File

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The ControlExtension annotation type is used to annotate a control extension interface.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ControlExtension
{
// Members parameterizing the control extension will be added here
}

View File

@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.beehive.controls.api.assembly.ControlAssembler;
import org.apache.beehive.controls.api.assembly.DefaultControlAssembler;
/**
* The ControlImplementation annotation type is used to annotate the implementation class for a
* Java Control. It marks the class as a control implementation and (in the future) parameterizes
* it.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ControlImplementation
{
/** class name for the Class (which implements
* com.bea.control.assembly.ControlAssembler) whose assemble()
* method is called at assembly time - if left Void then no
* special assembly is needed
*/
Class assemblyHelperClass() default java.lang.Void.class; // DEPRECATED
/**
* Class that implements ControlAssembler, which gets called at assembly time.
* Default implementation does nothing.
*/
Class<? extends ControlAssembler> assembler() default DefaultControlAssembler.class;
/**
* Specifies whether the control implementation class contains state that should be
* serialized as part of the containing Control/JavaBean or is fully stateless/transient.
*/
boolean isTransient() default false; // default to assuming stateful
}

View File

@ -0,0 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The ControlInterface annotation type is used to annotate a control public interface.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ControlInterface
{
/**
* Placeholder string used in defaultBinding attr. Tools and runtime should replace
* instances of INTERFACE_NAME found in values of defaultBinding with the fully
* qualified name of the interface annotated with @ControlInterface.
*/
static final String INTERFACE_NAME = "<InterfaceName>";
/**
* Specify the fully qualified name of the control implementation for this control interface.
* If no value is specified the implementation will be the name of the interface with 'Impl' appended.
* */
String defaultBinding() default INTERFACE_NAME + "Impl";
/**
* @deprecated Replaced by checker() element.
*/
Class<? extends ControlChecker> checkerClass() default DefaultControlChecker.class;
/**
* Used by control authors wishing to enforce rich semantic validation on extension and field
* instance declarations of their controls. By supplying a ControlChecker implementation
* (a "checker") and associating it with your control's public interface, when an
* extension of your control is processed at build-time, the checker will be invoked and
* can do rich validation of the extension type and field instances via introspection and
* analysis of the control extension's type structure, signatures and annotations.
* @see org.apache.beehive.controls.api.bean.ControlChecker
*/
Class<? extends ControlChecker> checker() default DefaultControlChecker.class;
}

View File

@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The ControlReferences annotation type is used to annotate a control client
* type, listing any control types that the client uses purely programmatically
* (and not declaratively). Tools will treat the union of the set of types
* annotated w/ @Control and the types listed in @ControlReferences as the
* complete set of controls used by a client.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ControlReferences
{
Class[] value() default {};
}

View File

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

View File

@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.Declaration;
/**
* The default or "empty" control checker that assigned to an @ControlInterface's
* controlChecker attribute if none is provided.
*/
public final class DefaultControlChecker implements ControlChecker
{
public void check(Declaration decl, AnnotationProcessorEnvironment env) { };
}

View File

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.reflect.Method;
/**
* The Extensible interface is implemented by a Java Control implementation class if the
* control defines an extensibility model that allows extended operations to be declared
* using a JCX interface.
* <p>
* The interface provides the <code>invoke</code> method, that is called whenever an
* extended operation is called by the client at run time.
*/
public interface Extensible
{
/**
* Called by the Controls runtime to handle calls to methods of an
* extensible control.
* <p>
* @param method The extended operation that was called.
* @param args Parameters of the operation.
* @return The value that should be returned by the operation.
* @throws java.lang.Throwable any exception declared on the extended operation may be
* thrown. If a checked exception is thrown from the implementation that is not declared
* on the original interface, it will be wrapped in a ControlException.
*/
public Object invoke(Method method, Object[] args) throws Throwable;
}

View File

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used on control interfaces to specify any external property sets that
* the control uses. External property sets are property sets that are
* their own top-level interfaces, i.e. not nested.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ExternalPropertySets
{
Class[] value();
}

View File

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to specify the desired threading policy to apply to a control
* implementation type. See {@link ThreadingPolicy}. Only permitted
* on classes that are also annotated with {@link ControlImplementation}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Threading
{
ThreadingPolicy value() default ThreadingPolicy.SINGLE_THREADED;
}

View File

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.bean;
/**
* Specifies threading policy for control implementations. The constants
* of this enumerated type describe the threading policies that apply
* during execution of controls. They are used in conjunction with the
* {@link Threading} annotation type to specify the responsibilities of
* the runtime infrastructure and control implementation with respect to
* threading.
*/
public enum ThreadingPolicy
{
/**
* When a control implementation is declared as SINGLE_THREADED, the
* controls infrastructure ensures that only a single thread will be
* executing in a particular instance of that control at any time.
* This is the default policy if no {@link Threading} annotation is
* specified.
*/
SINGLE_THREADED,
/**
* When a control implementation is declared as MULTI_THREADED, the
* controls infrastructure permits multiple threads to concurrently
* execute in instances of that control. It is then the responsibility
* of the implementation to ensure internal thread-safety using
* standard Java concurrency mechanisms. This policy may yield higher
* performance, at the cost of additional work on the implementor's part.
*/
MULTI_THREADED
}

View File

@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The Context annotation type is used to annotate a field within a control implementation
* class that refers to a contextual service. The Java Controls runtime will automatically
* initialize the field value to an appropriate provider of the requested service, or will
* throw a construction or deserialization error if no such provider is available.
*
* The following is a simple example:
*
* <code><pre>
* <sp>@ControlImplementation
* public class MyControlImpl
* {
* <sp>@Context
* ControlContext myContext;
* }
* </pre></code>
* This example declares a field named <code>myContext</code> that will automatically be
* initialized by the Java Controls runtime to refer to a provider of the
* <code>ControlContext</code> contextual service.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Context
{
}

View File

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

View File

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import org.apache.beehive.controls.api.bean.ControlBean;
import org.apache.beehive.controls.api.events.EventDispatcher;
/**
* The ControlContainerContext interface defines the basic contract between an external container
* of controls and the Controls runtime.
*/
public interface ControlContainerContext extends EventDispatcher, ControlBeanContext
{
/**
* Makes the ControlContainerContext instance the current active context. This is
* called at the beginning of the execution scope for the control container.
*/
public void beginContext();
/**
* Ends the active context associated with the ControlContainerContext. This is called
* at the end of the execution scope for the control container.
*/
public void endContext();
/**
* Returns a ControlHandle to the component containing the control. This handle can be
* used to dispatch events and operations to a control instance. This method will return
* null if the containing component does not support direct dispatch.
*/
public ControlHandle getControlHandle(ControlBean bean);
}

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import org.apache.beehive.controls.api.events.EventRef;
import java.lang.reflect.InvocationTargetException;
/**
* The ControlHandle interface defines a reference object to a control instance that enables
* control events to be fired on the control. Control container implementations will provide
* implementation of this interface that use container-specific dispatch mechanisms to locate
* the appropriate control container instance when events are fired.
*
* Classes implementing the ControlHandle interface should also implement the <code>
* java.io.Serializable</code> interface. This will enable handles to be serialized /
* deserialized as part of event queueing or routing.
*/
public interface ControlHandle
{
/**
* Returns the controlID of the target control referenced by this handle
*/
public String getControlID();
/**
* Delivers the specified event to the target control referenced by this handle.
*/
public Object sendEvent(EventRef event, Object [] args)
throws IllegalAccessException,IllegalArgumentException,InvocationTargetException;
}

View File

@ -0,0 +1,82 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.context;
import java.util.Stack;
/**
* The ControlThreadContext class manages the association between ControlContainerContexts
* and threads of execution. For a given thread of execution, the beginning and ending of
* contexts will always be nested (never interleaved), so each thread will maintain its own
* stack of currently executing contexts. This can be used to reassociate with the current
* active context.
*/
public class ControlThreadContext
{
/**
* This thread local maintains a per-thread stack of ControlContainerContext instances.
*/
private static ThreadLocal<Stack<ControlContainerContext>> _threadContexts =
new ThreadLocal<Stack<ControlContainerContext>>();
/**
* Returns the active ControlContainerContext for the current thread, or null if no
* context is currently active.
* @return the current active ControlContainerContext
*/
public static ControlContainerContext getContext()
{
Stack<ControlContainerContext> contextStack = _threadContexts.get();
if (contextStack == null || contextStack.size() == 0)
return null;
return contextStack.peek();
}
/**
* Defines the beginning of a new control container execution context.
*/
public static void beginContext(ControlContainerContext context)
{
Stack<ControlContainerContext> contextStack = _threadContexts.get();
if (contextStack == null)
{
contextStack = new Stack<ControlContainerContext>();
_threadContexts.set(contextStack);
}
contextStack.push(context);
}
/**
* Ends the current control container execution context
* @throws IllegalStateException if there is not current active context or it is not
* the requested context.
*/
public static void endContext(ControlContainerContext context)
{
Stack<ControlContainerContext> contextStack = _threadContexts.get();
if (contextStack == null || contextStack.size() == 0)
throw new IllegalStateException("No context started for current thread");
if (contextStack.peek() != context)
throw new IllegalStateException("Context is not the current active context");
contextStack.pop();
}
}

View File

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

View File

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The Client annotation type is used to mark fields in a Control implementation class
* that define client event proxies.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Client
{
}

View File

@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.reflect.InvocationTargetException;
import org.apache.beehive.controls.api.context.ControlContainerContext;
import org.apache.beehive.controls.api.context.ControlHandle;
import org.apache.beehive.controls.api.context.ControlThreadContext;
/**
* The EventDispatchHelper class is a simple implementation of the EventDispatcher interface
* that is suitable for use <b>inside</b> the execution context of a control container. It
* assumes that you are already running inside the target container instance, and all that is
* required is the correct routing of the event to the correct control.
*/
public class EventDispatchHelper implements EventDispatcher
{
public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
//
// Obtain the current active control container context
//
ControlContainerContext context = ControlThreadContext.getContext();
if (context == null)
throw new IllegalStateException("No active control container context");
//
// Dispatch the event using it.
//
return context.dispatchEvent(target, event, args);
}
}

View File

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.reflect.InvocationTargetException;
import org.apache.beehive.controls.api.context.ControlHandle;
/**
* The EventDispatcher interface defines the method signature that a container supporting
* the external dispatch of Control events would implement.
*/
public interface EventDispatcher
{
/**
* Dispatches a Control event to a target control.
* @param target the target control
* @param event the event to deliver to the control
* @param args the parameters to the control event
* @throws IllegalAccessException the underlying event method is not accessible due to
* access control.
* @throws IllegalArgumentException the target is not valid, the event is not a valid event
* type for the requested target, or the argument types do not match the event
* signature.
* @throws InvocationTargetException wraps any exception thrown by the underlying event
* handler.
*/
public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException;
}

View File

@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.rmi.RemoteException;
import org.apache.beehive.controls.api.context.ControlHandle;
/**
* The EventDispatcherRemote interface defines the event dispatch signature when event
* dispatching is happening via RMI.
*
* @see org.apache.beehive.controls.api.events.EventDispatcher
*/
public interface EventDispatcherRemote
{
/**
* Dispatches a Control event to a target control.
* @param target the target control
* @param event the event to deliver to the control
* @param args the parameters to the control event
* @throws RemoteException wraps any exception thrown during event dispatch
*/
public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
throws RemoteException;
}

View File

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The EventHandler annotation type is used to mark a method that provides the event handler
* implementation for a Control event.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface EventHandler
{
/**
* The field name of the Java control event source. This must be an @Control field declared
* on the class defining the event handler method (or on a superclass if the field is not
* declared to be private).
*/
String field();
/**
* The EventSet interface that declares the event. This must be a valid EventSet interface
* associated with the control type of the <code>field</code> member.
*/
Class eventSet();
/**
* The name of the handled event. This must be the name of a method declared on the EventSet
* interface referenced by the <code>eventSet</code> member. The annotated method must have
* an event signature that <b>exactly</b> matches one of the event methods with this name.
*/
String eventName();
}

View File

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

View File

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

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.events;
import java.rmi.RemoteException;
import org.apache.beehive.controls.api.context.ControlHandle;
/**
* The RemoteEventDispatcher interface defines the method signature that a container supporting
* the external dispatch of Control events would implement if events can be dispatched using RMI.
*/
public interface RemoteEventDispatcher
{
/**
* Dispatches a Control event to a target control.
* @param target the target control
* @param event the event to deliver to the control
* @param args the parameters to the control event
* @throws IllegalAccessException the underlying event method is not accessible due to
* access control.
* @throws IllegalArgumentException the target is not valid, the event is not a valid event
* type for the requested target, or the argument types do not match the event
* signature.
* @throws InvocationTargetException wraps any exception thrown by the underlying event
* handler.
*/
public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
throws RemoteException;
}

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The FeatureInfo annotation type defines a JSR-175 syntax for annotating a Control to
* provide BeanInfo FeatureDescriptor information for the bean, its properties, methods,
* or events.
* <p>
* The elements of FeatureInfo correspond 1-to-1 with the information exposed by the
* <code>java.beans.FeatureDescriptor</code> class.
*
* @see java.beans.FeatureDescriptor
*/
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface BeanInfo
{
/**
* The NoCustomizer class can be used as the value of the customizerClass attribute to
* indicate that the bean has no customizer.
*/
static public class NoCustomizer {}
public Class customizerClass() default NoCustomizer.class;
}

View File

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The EventSetInfo annotation type defines a JSR-175 syntax for annotating a Control
* property declaration to provide java.beans.EventSetDescriptor information. Generic
* feature information is defined using the <code>FeatureInfo</code> annotation type
* <p>
* The elements of EventStInfo correspond 1-to-1 with the information exposed by the
* <code>java.beans.EventSetDescriptor</code> class.
*
* @see java.beans.EventSetDescriptor
*/
@Target({ElementType.TYPE}) // appears on EventSet interface declaration
public @interface EventSetInfo
{
public boolean isUnicast() default false; // single listener model
public boolean isDefault() default true; // is the default event set
}

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The FeatureAttribute annotation type defines a JSR-175 syntax for specifying JavaBean
* FeatureDescriptor attributes associated with a Control.
*
* @see org.apache.beehive.controls.api.packaging.FeatureInfo
*/
public @interface FeatureAttribute
{
/* Specifies the feature attribute name */
public String name();
/* Specifies the feature attribute value */
public String value();
}

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The FeatureInfo annotation type defines a JSR-175 syntax for annotating a Control to
* provide BeanInfo FeatureDescriptor information for the bean, its properties, methods,
* or events.
* <p>
* The elements of FeatureInfo correspond 1-to-1 with the information exposed by the
* <code>java.beans.FeatureDescriptor</code> class.
*
* @see java.beans.FeatureDescriptor
*/
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface FeatureInfo
{
public String displayName() default ""; // default: use reflection name
public String name() default ""; // default: use reflection name
public String shortDescription() default "";
public boolean isExpert() default false;
public boolean isHidden() default false;
public boolean isPreferred() default false;
public FeatureAttribute [] attributes() default {};
}

View File

@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The ManifestAttribute annotation type defines a JSR-175 syntax for specifying JAR
* manifest attributes associated with a control type. The Beehive Controls packaging
* support will process these annotation during the construction of a JAR file that
* contains Controls.
*/
@Target({ElementType.TYPE})
public @interface ManifestAttribute
{
/* Specifies the manifest attribute name */
public String name();
/* Specifies the manifest attribute value */
public String value();
}

View File

@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.packaging;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* The ManifestAttributes annotation type enables a set of manifest attributes attributes
* to be defined for a given control type.
*
* @see org.apache.beehive.controls.api.packaging.ManifestAttribute
*/
@Target({ElementType.TYPE})
public @interface ManifestAttributes
{
/* Specifies the set of ManifestAttribute annotation values */
public ManifestAttribute [] value();
}

View File

@ -0,0 +1,49 @@
package org.apache.beehive.controls.api.packaging;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.beans.PropertyEditor;
/**
* The PropertyInfo annotation type defines a JSR-175 syntax for annotating a Control
* property declaration to provide java.beans.PropertyDescriptor information. Generic
* feature information is defined using the <code>FeatureInfo</code> annotation type
* <p>
* The elements of PropertyInfo correspond 1-to-1 with the information exposed by the
* <code>java.beans.PropertyDescriptor</code> class.
*
* @see java.beans.PropertyDescriptor
*/
@Target({ElementType.METHOD}) // appears on PropertySet method declaration (i.e. properties)
public @interface PropertyInfo
{
/**
* The NoEditor class can be used as the value of the editorClass attribute to
* indicate that the property has no editor
*/
static public class NoEditor {};
public boolean bound() default false; // Sends PropertyChange events
public boolean constrained() default false; // Sends VetoableChange events
public Class editorClass() default NoEditor.class; // default == no editor
}

View File

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

View File

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

View File

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Base properties that are present intrinsically on all controls.
*/
@PropertySet
@Target( {ElementType.TYPE, ElementType.FIELD} )
@Retention( RetentionPolicy.RUNTIME )
public @interface BaseProperties
{
/**
* Fully qualified classname of the implementation class for the control. If null,
* the default algorithm for * determining the implementation class will be used --
* basically, adding "Impl" to the control interface name.
*/
String controlImplementation() default "";
}

View File

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

View File

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

View File

@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.properties;
import java.lang.annotation.Annotation;
/**
* The PropertyMap interface represents a collection of ControlBean properties. Concrete
* implementations of this interface might derive property values from a local Map, Java 5.0
* annotations, external configuration, or other property sources.
*/
public interface PropertyMap
{
/**
* Returns the PropertySet or Control interface class associated with the PropertyMap.
*/
public Class getMapClass();
/**
* Sets a delegate base property map from which values will be derived if not found within
* the local property map.
*/
public void setDelegateMap(PropertyMap delegateMap);
/**
* Returns a delegate base property map from which values will be derived if not found within
* the local property map.
*/
public PropertyMap getDelegateMap();
/**
* Sets the property specifed by 'key' within this map.
*/
public void setProperty(PropertyKey key, Object value);
/**
* Returns the property value specified by 'key' within this map.
*/
public Object getProperty(PropertyKey key);
/**
* Returns true if the PropertyMap contains one or more values for the specified
* PropertySet, false otherwise
*/
public boolean containsPropertySet(Class<? extends Annotation> propertySet);
/**
* Returns a PropertySet proxy instance that derives its data from the contents of
* the property map. Will return null if the PropertyMap does not contain any properties
* associated with the specified PropertySet.
*/
public <T extends Annotation> T getPropertySet(Class<T> propertySet);
}

View File

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

View File

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

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.versioning;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used by the control author to specify the version (major.minor) of the control interface.
* Allowed on interfaces annotated with @ControlInterface. This version number
* is the basis for control versioning, and versioning constraints against it are enforced both at
* compile time and runtime.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Version
{
/**
* Major version number, typically used to track significant functionality changes.
*/
int major();
/**
* Minor version number, typically used to track small internal changes/fixes. Version
* constraints default to ignoring the minor version number in their comparisons, but may
* be configured to specify a particular minor version.
*/
int minor() default 0;
}

View File

@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.versioning;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies the minimum version of the control interface that this extension
* requires. Allowed on control extensions (interfaces annotated with
* <sp>@ControlExtension), and on control field declarations (fields annotated
* with @Control). The version requirement is enforced at compile time of
* extensions and control client, and at runtime when the appropriate control
* bean is classloaded.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface VersionRequired
{
/**
* The major version value required for this control extension or instance
* declaration to work. Any version number greater than or equal to this
* value will suffice, implying that this requirement is valid only when
* back compatibility is part of the contract when increasing the version
* number. Negative values mean that any major version is
* acceptable (in which case this annotation should probably just not be
* present).
*/
int major();
/**
* The minor version value required for this control extension or instance
* declaration to work. Any version number greater than or equal to this
* value will suffice. Negative values mean that any minor version is
* acceptable (the default case).
*/
int minor() default -1;
}

View File

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.api.versioning;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies the maximum version of the control interface that this implementation
* supports. Allowed on control implementations (interfaces annotated with
* <sp>@ControlImplementation). This version requirement is enforced at compile time
* of the implementation, and at runtime when the implementation is classloaded.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface VersionSupported
{
/**
* The major version of the control interface that this implementation
* supports. Any version number less than or equal to this value will suffice,
* implying that this constraint is only valid when backwards compatibility
* is part of the contract when increasing the version number. Negative
* values mean that any major version is acceptable (in which case this
* annotation should probably just not be
* present).
*/
int major();
/**
* The minor version of the control interface that this implementation
* supports. Any version number less than or equal to this value will suffice.
* Negative values mean that any minor version is acceptable (the default case).
*/
int minor() default -1;
}

View File

@ -0,0 +1,51 @@
<?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>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.beehive</groupId>
<artifactId>beehive-controls</artifactId>
<name>beehive-controls</name>
<version>@beehive.version@</version>
<dependencies>
<dependency>
<groupId>velocity</groupId>
<artifactId>velocity-dep</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>0.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,26 @@
#
# 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:$
#
#
# This configures APT so the ControlProcessorFactory can be used to process Control annotations
#
org.apache.beehive.controls.runtime.generator.apt.ControlAnnotationProcessorFactory
org.apache.beehive.controls.runtime.generator.apt.ControlClientAnnotationProcessorFactory
org.apache.beehive.controls.runtime.generator.apt.ControlMemberTypeAnnotationProcessorFactory
org.apache.beehive.controls.runtime.generator.apt.ControlSecondaryAnnotationProcessorFactory

View File

@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* A ControlAssemblyContext implementation supporting standard Enterprise app modules
*/
public class AppAssemblyContext
extends BaseAssemblyContext
implements ControlAssemblyContext.EntAppModule
{
public static class Factory
implements ControlAssemblyContext.Factory
{
public AppAssemblyContext newInstance( Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException
{
return new AppAssemblyContext( controlIntfOrExt, bindings, clients,
moduleRoot, moduleName, srcOutputRoot );
}
}
protected AppAssemblyContext( Class controlIntfOrExt, Map<String,String> bindings,
Set<String> clients, File moduleRoot,
String moduleName, File srcOutputRoot )
throws ControlAssemblyException
{
super( controlIntfOrExt, bindings, clients, moduleRoot, moduleName, srcOutputRoot );
}
public File getApplicationXml()
{
return new File( getModuleDir(), "META-INF" + File.separator + "application.xml" );
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* A ControlAssemblyContext implementation supporting standard EJB modules
*/
public class EJBAssemblyContext
extends BaseAssemblyContext
implements ControlAssemblyContext.EJBModule
{
public static class Factory implements ControlAssemblyContext.Factory
{
public EJBAssemblyContext newInstance( Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException
{
return new EJBAssemblyContext( controlIntfOrExt, bindings, clients,
moduleRoot, moduleName, srcOutputRoot );
}
}
protected EJBAssemblyContext( Class controlIntfOrExt, Map<String,String> bindings,
Set<String> clients, File moduleRoot,
String moduleName, File srcOutputRoot )
throws ControlAssemblyException
{
super( controlIntfOrExt, bindings, clients, moduleRoot, moduleName, srcOutputRoot );
}
public File getEjbJarXml()
{
return new File( getModuleDir(), "META-INF" + File.separator + "ejb-jar.xml");
}
}

View File

@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.assembly;
import org.apache.beehive.controls.api.assembly.ControlAssemblyContext;
import org.apache.beehive.controls.api.assembly.ControlAssemblyException;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* A ControlAssemblyContext implementation supporting standard web-app modules
*/
public class WebAppAssemblyContext
extends BaseAssemblyContext
implements ControlAssemblyContext.WebAppModule
{
public static class Factory
implements ControlAssemblyContext.Factory
{
public WebAppAssemblyContext newInstance( Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException
{
return new WebAppAssemblyContext( controlIntfOrExt, bindings, clients,
moduleRoot, moduleName, srcOutputRoot );
}
}
protected WebAppAssemblyContext(Class controlIntfOrExt,
Map<String,String> bindings,
Set<String> clients,
File moduleRoot,
String moduleName,
File srcOutputRoot )
throws ControlAssemblyException
{
super( controlIntfOrExt, bindings, clients, moduleRoot, moduleName, srcOutputRoot );
}
public File getWebXml()
{
return new File( getModuleDir(), "WEB-INF" + File.separator + "web.xml");
}
}

View File

@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
/**
* The AdaptorPersistenceDelegate class supports the XML persistance of Control Client Event
* Adaptor instances by implementing the <code>java.beans.PersistenceDelegate</b> API, and
* overriding the default persistance algorithm based upon the runtime structure for Controls.
*/
public class AdaptorPersistenceDelegate extends DefaultPersistenceDelegate
{
/**
* PersistenceDelegate.instantiate()
*/
protected Expression instantiate(Object oldInstance, Encoder out)
{
if (! (oldInstance instanceof EventAdaptor))
return super.instantiate(oldInstance, out);
//
// An implementation instance is actually constructed at decode time by calling
// ControlBean.ensureControl on the parent bean. This will create a new impl
// instance and run the impl initializer on it.
//
return new Expression(oldInstance, oldInstance.getClass(), "new",
new Object[] { ((EventAdaptor)oldInstance).getClient() });
}
/**
* PersistenceDelegate.initialize()
*/
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out)
{
super.initialize(type, oldInstance, newInstance, out);
}
/**
* PersistenceDelegate.writeObject()
*/
public void writeObject(Object oldInstance, Encoder out)
{
super.writeObject(oldInstance, out);
}
}

View File

@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.PersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
/**
* The AnnotatedElementMapPersistenceDelegate is an XMLEncoder PersistenceDelegate for
* the <code>org.apache.beehive.controls.api.properties.AnnotatedElementMap</code>
* class.
*/
public class AnnotatedElementMapPersistenceDelegate extends PersistenceDelegate
{
protected Expression instantiate(Object oldInstance, Encoder out)
{
//
// Modify the default constructor to pass in the AnnotatedElement wrapped by the map
//
AnnotatedElementMap aem = (AnnotatedElementMap)oldInstance;
return new Expression(aem, aem.getClass(), "new",
new Object [] { aem.getAnnotatedElement() });
}
}

View File

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

View File

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
/**
* The BeanListener class acts as the abstract base class for generated event listeners
* associated with a ControlBean.
*/
abstract public class BeanListener
implements java.io.Serializable
{
protected BeanListener()
{
this(null);
}
protected BeanListener(Object source)
{
_source = source;
}
abstract public BeanListener cloneListener(Object source);
public Object getSource() {
return _source;
}
Object _source;
}

View File

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

View File

@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.lang.reflect.AnnotatedElement;
import org.apache.beehive.controls.api.context.ControlBeanContext;
import org.apache.beehive.controls.api.properties.PropertyMap;
import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
import org.apache.beehive.controls.api.versioning.VersionRequired;
import org.apache.beehive.controls.api.versioning.Version;
/**
* The ClientInitializer class is an abstract base class that all generated Control
* client initializer classes will extend. It provides common utilities and supporting code
* for initialization, and has a shared package relationship with the base ControlBean
* class providing access to internals not available in a more general context.
*/
abstract public class ClientInitializer
{
/**
* Enforces the VersionRequired annotation at runtime (called when an instance of a control is annotated
* with VersionRequired). Throws a ControlException if enforcement fails.
*
* @param versionRequired the value of the VersionRequired annotation on a control field
*/
protected static void enforceVersionRequired( ControlBean control, VersionRequired versionRequired )
{
Class controlIntf = ControlUtils.getMostDerivedInterface( control.getControlInterface() );
Version versionPresent = (Version) controlIntf.getAnnotation( Version.class );
if ( versionPresent != null )
{
ControlBean.enforceVersionRequired( controlIntf.getCanonicalName(), versionPresent, versionRequired );
}
}
/**
* Returns the annotation map for the specified element.
*/
public static PropertyMap getAnnotationMap(ControlBeanContext cbc, AnnotatedElement annotElem)
{
if ( cbc == null )
return new AnnotatedElementMap(annotElem);
return cbc.getAnnotationMap(annotElem);
}
}

View File

@ -0,0 +1,61 @@
/*
* 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

View File

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

View File

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

View File

@ -0,0 +1,97 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import org.apache.beehive.controls.api.bean.ControlInterface;
import org.apache.beehive.controls.api.bean.ControlExtension;
import org.apache.beehive.controls.api.ControlException;
/**
* Utilities used by the Controls runtime.
*/
public final class ControlUtils {
private ControlUtils() {}
/**
* Implements the default control implementation binding algorithm ( <InterfaceName> + "Impl" ). See
* documentation for the org.apache.beehive.controls.api.bean.ControlInterface annotation.
*
* @param implBinding the value of the defaultBinding attribute returned from a ControlInterface annotation
* @param controlClass the actual name of the interface decorated by the ControlInterface annotation
* @return the resolved defaultBinding value
*/
public static String resolveDefaultBinding( String implBinding, String controlClass )
{
int intfIndex = implBinding.indexOf(ControlInterface.INTERFACE_NAME);
if (intfIndex >= 0)
{
implBinding = implBinding.substring(0,intfIndex) + controlClass +
implBinding.substring(intfIndex +
ControlInterface.INTERFACE_NAME.length());
}
return implBinding;
}
/**
* Returns the default binding based entirely upon annotations or naming conventions.
* @param controlIntf the control interface class
* @return the class name of the default control implementation binding
*/
static String getDefaultControlBinding(Class controlIntf)
{
controlIntf = getMostDerivedInterface(controlIntf);
ControlInterface intfAnnot =
(ControlInterface)controlIntf.getAnnotation(ControlInterface.class);
String implBinding = intfAnnot.defaultBinding();
implBinding = resolveDefaultBinding( implBinding, controlIntf.getName() );
return implBinding;
}
/**
* Computes the most derived ControlInterface for the specified ControlExtension.
* @param controlIntf
* @return the most derived ControlInterface
*/
static Class getMostDerivedInterface(Class controlIntf)
{
while (controlIntf.isAnnotationPresent(ControlExtension.class))
{
Class [] intfs = controlIntf.getInterfaces();
boolean found = false;
for (int i = 0; i < intfs.length; i++)
{
if (intfs[i].isAnnotationPresent(ControlExtension.class) ||
intfs[i].isAnnotationPresent(ControlInterface.class))
{
controlIntf = intfs[i];
found = true;
break;
}
}
if (!found)
{
throw new ControlException("Can't find base control interface for " + controlIntf);
}
}
return controlIntf;
}
}

View File

@ -0,0 +1,57 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
$Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import org.apache.beehive.controls.api.bean.ControlBean;
import org.apache.beehive.controls.api.context.ControlBeanContext;
import org.apache.beehive.controls.spi.context.ControlBeanContextFactory;
/**
* Default implementation of the {@link ControlBeanContextFactory} that simply creates an instance of a
* {@link ControlBeanContext} given the current {@link ControlBean}.
*/
/* package */ class DefaultControlBeanContextFactory
implements ControlBeanContextFactory {
/**
* Create the {@link ControlBeanContext} for the {@link ControlBean}.
* @param controlBean
* @return the {@link ControlBeanContext}
*/
public ControlBeanContext instantiate(ControlBean controlBean) {
if(!(controlBean instanceof org.apache.beehive.controls.runtime.bean.ControlBean))
throw new IllegalArgumentException("The ControlBean of type \"" +
controlBean.getClass().getName() +
"\" is unsupported. The ControlBean must extend " +
org.apache.beehive.controls.runtime.bean.ControlBean.class.getName());
/*
The provided ControlBean is a "api.bean.ControlBean"; this factory implementation only creates
ControlBeanContext implementations for "runtime.bean.ControlBean" types. Ensuare that this is
of that type.
*/
org.apache.beehive.controls.runtime.bean.ControlBean runtimeControlBean =
(org.apache.beehive.controls.runtime.bean.ControlBean)controlBean;
/*
Create a simple new ControlBeanContext.
*/
return new org.apache.beehive.controls.runtime.bean.ControlBeanContext(runtimeControlBean);
}
}

View File

@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
/**
* The EventAdaptor interface will be implemented by all code-generated event adaptor classes
* used to deliver control events to clients.
*/
public interface EventAdaptor
{
/**
* Returns the client instance that will be the target of the event.
*/
Object getClient();
}

View File

@ -0,0 +1,74 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.util.Iterator;
import java.util.LinkedList;
/**
* The EventNotifier class provides basic callback listener management and event delivery
* services for ControlBean instances.
*/
public class EventNotifier implements java.io.Serializable
{
/**
* Adds a new callback event listener for this EventNotifier
*/
synchronized public void addListener(Object listener)
{
_listeners.add(listener);
}
/**
* Remove an existing callback event listener for this EventNotifier
*/
synchronized public void removeListener(Object listener)
{
if (!_listeners.contains(listener))
throw new IllegalStateException("Invalid listener, not currently registered");
_listeners.remove(listener);
}
/**
* Returns an iterator over the full set of listeners
*/
public Iterator listenerIterator()
{
return _listeners.iterator();
}
/**
* Returns the number of registered listeners
*/
public int getListenerCount()
{
return _listeners.size();
}
/**
* Returns the listener list in array form
*/
public void getListeners(Object [] listeners)
{
_listeners.toArray(listeners);
}
private LinkedList _listeners = new LinkedList();
}

View File

@ -0,0 +1,75 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
/**
* The ImplInitializer class is an abstract base class that all generated Control
* initalization classes will extend. It provides common utilities and supporting code
* for initialization, and has a shared package relationship with the base ControlBean
* class providing access to internals not available in a more general context.
*/
abstract public class ImplInitializer
{
/**
* Initializes a new ControlImplementation instance associated with the specified bean.
*/
public void initialize(ControlBean bean, Object target)
{
initServices(bean, target);
initControls(bean, target);
initEventProxies(bean, target);
}
/**
* Initializes all contextual services required by the target implementation instance.
* The default initializer implementation is a noop, but will be overridden by
* generated subclasses that contain contextual services.
*/
public void initServices(ControlBean bean, Object target) { };
/**
* Resets all contextual services on the target implementation instance to null.
* The default initializer implementation is a noop, but will be overridden by
* generated subclasses that contain contextual services.
*/
public void resetServices(ControlBean bean, Object target) { };
/**
* Initializes all nested controls required by the target implementation instance.
* The default initializer implementation is a noop, but will be overridden by
* generated subclasses that contain nested controls
*/
public void initControls(ControlBean bean, Object target) { };
/**
* Initializes all event proxies required by the target implementation instance.
* The default initializer implementation is a noop, but will be overridden by
* generated subclasses that contain event proxies
*/
public void initEventProxies(ControlBean bean, Object target) { };
/**
* Returns the ControlBean event notifier for the specified eventSet
*/
public Object getEventNotifier(ControlBean bean, Class eventSet)
{
return bean.getEventNotifier(eventSet);
}
}

View File

@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.BeanInfo;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PersistenceDelegate;
import java.beans.PropertyDescriptor;
import java.beans.Statement;
import java.beans.XMLEncoder;
import java.util.Set;
import org.apache.beehive.controls.api.ControlException;
/**
* The ImplPersistenceDelegate class supports the XML persistance of Control Implementation
* instances by implementing the <code>java.beans.PersistenceDelegate</b> API, and overriding
* the default persistance algorithm based upon the runtime structure for Controls.
* <p>
*/
public class ImplPersistenceDelegate extends DefaultPersistenceDelegate
{
/**
* PersistenceDelegate.instantiate()
*/
protected Expression instantiate(Object oldInstance, Encoder out)
{
//
// An implementation instance is actually constructed at decode time by calling
// ControlBean.ensureControl on the parent bean. This will create a new impl
// instance and run the impl initializer on it.
//
return new Expression(((XMLEncoder)out).getOwner(), "ensureControl", null);
}
/**
* PersistenceDelegate.initialize()
*/
protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out)
{
super.initialize(type, oldInstance, newInstance, out);
}
/**
* PersistenceDelegate.writeObject()
*/
public void writeObject(Object oldInstance, Encoder out)
{
super.writeObject(oldInstance, out);
}
}

View File

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

View File

@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.lang.reflect.Method;
/**
* The InvokeListener interface can be implemented by contextual services or helper
* classes associated with a ControlBean that want pre/post hook notifications of
* invocations occuring on a ControlBean.
*
* Hooking is "read only". An InvokeListener cannot modify the invoked method,
* arguments, return value or thrown exceptions in any way.
*/
public interface InvokeListener extends java.util.EventListener
{
/**
* Called just prior to invoking an operation or callback event on a control.
*/
public void preInvoke(Method m, Object [] args);
/**
* Called just after inovcation of an operation or callback event on a control
*/
public void postInvoke(Object retval, Throwable t);
}

View File

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

View File

@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.util.TooManyListenersException;
/**
* The UnicastEventNotifier class provides basic callback listener management and event delivery
* services for unicast EventSets on ControlBean instances.
*/
public class UnicastEventNotifier implements java.io.Serializable
{
/**
* Adds a new callback event listener for this EventNotifier. This method will also
* perform a check to see if there is already a register listener, and throw a
* <code>java.util.TooManyListenersException</code> if there is already a registered
* listener.
*/
synchronized public void addListener(Object listener) throws TooManyListenersException
{
if (_listener != null)
throw new TooManyListenersException("Callback listener is already registered");
_listener = listener;
}
/**
* Remove an existing callback event listener for this EventNotifier
*/
synchronized public void removeListener(Object listener)
{
if (_listener != listener)
{
throw new IllegalStateException("Invalid listener, not currently registered");
}
_listener = null;
}
/**
* Returns the listener associated with this EventNotifier
*/
public Object getListener()
{
return _listener;
}
/**
* Returns the number of registered listeners
*/
public int getListenerCount()
{
return (_listener != null) ? 1 : 0;
}
/**
* Returns the listener list in array form
*/
public void getListeners(Object [] listeners)
{
if (_listener != null)
listeners[0] = _listener;
}
private Object _listener;
}

View File

@ -0,0 +1,105 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
package org.apache.beehive.controls.runtime.bean;
import java.beans.beancontext.BeanContextServices;
import java.beans.beancontext.BeanContextServiceProvider;
import java.util.Iterator;
import java.util.Collections;
import org.apache.beehive.controls.spi.context.ControlBeanContextFactory;
import org.apache.beehive.controls.runtime.webcontext.ControlBeanContextServicesSupport;
/**
* <p>
* This class acts as a ControlBeanContextFactoryProvider that exposes this factory as a contextual service
* from inside of a ControlBeanContext.
* </p>
* <p>
* <b>Note:</b> This class, the service provider, and the contextual service it provides are considerd an implementation
* detail and <b>should not</b> be used from user code.
* </p>
*/
public class WebContextFactoryProvider
implements BeanContextServiceProvider {
private static final WebContextFactoryProvider theProvider = new WebContextFactoryProvider();
private static final WebControlBeanContextFactory theFactory = new WebControlBeanContextFactory();
public static final ControlBeanContext.BeanContextServicesFactory WEB_CONTEXT_BCS_FACTORY =
new WebContextBeanContextServicesFactory();
public static BeanContextServiceProvider getProvider() {
return theProvider;
}
private WebContextFactoryProvider() {
}
public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector) {
return theFactory;
}
public void releaseService(BeanContextServices bcs, Object requestor, Object service) {
}
public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) {
return Collections.EMPTY_LIST.iterator();
}
/**
* <p>
* {@link ControlBeanContextFactory} implementation that provides a {@link ControlBeanContext} object
* used for web-tier control containment.
* </p>
* <p>
* <b>Note:</b> This factory is considerd an implementation detail and <b>should not</b> be referenced from user code.
* </p>
*/
/*package*/ static class WebControlBeanContextFactory
implements ControlBeanContextFactory {
public org.apache.beehive.controls.api.context.ControlBeanContext instantiate
(org.apache.beehive.controls.api.bean.ControlBean controlBean) {
if(!(controlBean instanceof ControlBean))
throw new IllegalArgumentException("The ControlBean of type \"" +
controlBean.getClass().getName() +
"\" is unsupported. The ControlBean must extend " +
ControlBean.class.getName());
ControlBean runtimeControlBean = (ControlBean)controlBean;
return new ControlBeanContext(runtimeControlBean, WEB_CONTEXT_BCS_FACTORY);
}
}
/*package*/ static class WebContextBeanContextServicesFactory
extends ControlBeanContext.BeanContextServicesFactory {
protected BeanContextServices instantiate(ControlBeanContext controlBeanContext) {
return new ControlBeanContextServicesSupport(controlBeanContext);
/* The java implementation of the BeanContext support classes,
not currently used by Beehive due to performance issues.
return new java.beans.beancontext.BeanContextServicesSupport(controlBeanContext);
*/
}
}
}

View File

@ -0,0 +1,87 @@
/*
* 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>();
}

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