initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4cc2ad2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,30 @@
+# Java #
+*.class
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# IDEA #
+*.iml
+.idea
+*~
+
+# eclipse specific git ignore
+.project
+.metadata
+.classpath
+.settings/
+
+# Maven files #
+data/
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+
+# Misc #
+*.log
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..37f22ad
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,4 @@
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/README.adoc b/README.adoc
new file mode 100644
index 0000000..c7a6c63
--- /dev/null
+++ b/README.adoc
@@ -0,0 +1,171 @@
+= Chatterbox
+
+A collection of sample JCA connectors.
+
+== Projects
+
+The following connectors are available:
+
+- IMAP
+- Twitter
+- XMPP
+- Slack
+
+These connectors demonstrate inbound and outbound connectivity, using strongly typed method parameters and an API based
+on JAX-RS +@Path+ / +@PathParam+ annotations.
+
+== Annotations
+
+Each connector has an API module that defines a number of annotations. The annotations are defined in pairs, such as
++@Body+ and +@BodyParam+. The method parameter (+@Body+ in this example) optionally allows a regular expression to be
+specified as the annotation value. This regular expression should match for the method to be called. The matching +Param+
+annotation can be specified on a parameter for the value to be passed into the method. The parameter can optionally
+reference a group in the regular expression on the matching method annotation.
+
+Consider the following example:
+
+[source,java,numbered]
+----
+ @MessageDriven
+ public class InboxReader implements MailListener {
+
+ private static final Logger LOGGER = Logger.getLogger(InboxReader.class.getName());
+
+ @Subject("Order {orderId: \\d+}")
+ public void logMessage(@FromParam final String from, @SubjectParam final String subject, @BodyParam final String message
+ @SubjectParam("orderId") final Integer orderId) {
+ // TODO: logic goes here
+ }
+
+ }
+----
+
+This method will be called for any incoming e-mail where the subject is in the format "Order XXX" where XXX is numerical
+and the orderId parameter is set to the part of the subject that matches the order ID. A +Param+ annotation without a
+value set, such as +@SubjectParam+ will receive the full value as opposed to the matching regex group.
+
+== Project structure
+
+Each connector consists of an API, implementation, RAR module and a sample WAR file demonstrating simple cases of using
+the connector.
+
+In TomEE, the API module should be copied to the +lib/+ directory, the RAR module deployed under +apps/+ and the sample
+WAR deployed in +webapps/+.
+
+The WAR module for each project can be executed using the Maven tomee:run plugin. To use this, add the necessary config
+settings to ~/.openejb/system.properties (see tables for each connector below) and run `mvn tomee:run` in the WAR module
+directory.
+
+== IMAP connector
+
+The IMAP connector will poll the inbox folder for a specified IMAP account every 10 seconds, and invoke matching methods on MDBs that
+implement the +MailListener+ interface.
+
+The following annotations are available:
+
+|===
+| Method Annotation | Parameter Annotation | Description
+| @From
+| @FromParam
+| Matches the sender of the email. Where a value is specified, on the +@FormParam+ annotation, the value of the parameter will be the portion of the sender's address matching the regex group
+| @Subject
+| @SubjectParam
+| Matches the subject of the email. Where a value is specified, on the +@SubjectParam+ annotation, the value of the parameter will be the portion of the subject matching the regex group
+| @Body
+| @BodyParam
+| Matches the message body of the email. Where a value is specified, on the +@BodyParam+ annotation, the value of the parameter will be the portion of the message body matching the regex group
+|===
+
+This connector has the following configuration options:
+
+|===
+| Property name | Default | Description
+| Host
+| No default
+| The IMAP host to connect to
+| Port
+| 993
+| The IMAP port
+| Username
+| No default
+| The username to fetch mail for
+| Password
+| No default
+| The password for the user account
+|===
+
+== Twitter connector
+
+The Twitter connector opens a long running stream to the specified user's tweets, and invokes MDBs implementing the +TwitterUpdates+
+interface. New tweets where the status and/or screen name of the Tweeter match the annotations on the MDB method will cause the
+method to be invoked.
+
+The following annotations are available:
+
+|===
+| Method Annotation | Parameter Annotation | Description
+| @Tweet
+| @TweetParam
+| Matches the full tweet. Where a value is specified, on the +@TweetParam+ annotation, the value of the parameter will be the portion of the tweet matching the regex group.
+| @User
+| @UserParam
+| Matches the screen name of the user tweeting. Where a value is specified, on the +@UserParam+ annotation, the value of the parameter will be the portion of the user's screen name matching the regex group
+|===
+
+This connector has the following configuration options:
+
+|===
+| Property name | Description
+| ConsumerKey
+| The OAuth Consumer key
+| ConsumerSecret
+| The OAuth Consumer secret
+| AccessToken
+| The OAuth Access token
+| AccessTokenSecret
+| The OAuth Access token secret
+|===
+
+These credentials can be obtained by creating a new application on the Twitter Developers site, and authorizing the
+application for your Twitter account.
+
+== XMPP connector
+
+The XMPP connector is a bidirectional connector. MDBs can be invoked on messages being sent to the account signed into
+the connector. ConnectionFactory and Connection classes can be used in managed components to send messages to other
+users.
+
+The following annotations are available:
+
+|===
+| Method Annotation | Parameter Annotation | Description
+| @Sender
+| @SenderParam
+| Matches the sender of the message. Where a value is specified, on the +@SenderParam+ annotation, the value of the parameter will be the portion of the sender's address matching the regex group
+| @MessageText
+| @MessageTextParam
+| Matches the text of the message. Where a value is specified, on the +@MessageTextParam+ annotation, the value of the parameter will be the portion of the message matching the regex group
+|===
+
+This connector has the following configuration options:
+
+|===
+| Property name | Default | Description
+| Host
+| No default
+| The XMPP host to connect to
+| Port
+| 5222
+| The XMPP port
+| Username
+| No default
+| The username to fetch mail for
+| Password
+| No default
+| The password for the user account
+| Service name
+| No default
+| The XMPP service to connect to
+|===
+
+
diff --git a/chatterbox-imap/chatterbox-imap-api/pom.xml b/chatterbox-imap/chatterbox-imap-api/pom.xml
new file mode 100644
index 0000000..7621852
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-imap-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-imap-api</artifactId>
+ <packaging>jar</packaging>
+ <name>Chatterbox :: IMAP :: API</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.arquillian>1.1.1.Final</version.arquillian>
+ <version.shrinkwrap.descriptor>2.0.0-alpha-5</version.shrinkwrap.descriptor>
+ <version.shrinkwrap.shrinkwrap>1.0.1</version.shrinkwrap.shrinkwrap>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/Body.java b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/Body.java
new file mode 100644
index 0000000..8f4328f
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/Body.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.api;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Body {
+ String value() default "";
+}
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/BodyParam.java b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/BodyParam.java
new file mode 100644
index 0000000..db86395
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/BodyParam.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.api;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface BodyParam {
+ String value() default "";
+}
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/From.java b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/From.java
new file mode 100644
index 0000000..72d9148
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/From.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.api;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface From {
+ String value() default "";
+}
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/FromParam.java b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/FromParam.java
new file mode 100644
index 0000000..1cb908e
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/FromParam.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.api;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface FromParam {
+ String value() default "";
+}
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/InvokeAllMatches.java b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/InvokeAllMatches.java
new file mode 100644
index 0000000..b4711b5
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/InvokeAllMatches.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.api;
+
+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;
+
+@Inherited
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface InvokeAllMatches {
+}
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/MailListener.java b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/MailListener.java
new file mode 100644
index 0000000..0137eb4
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/MailListener.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.api;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public interface MailListener {
+}
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/Subject.java b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/Subject.java
new file mode 100644
index 0000000..a7a96eb
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/Subject.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.api;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Subject {
+ String value() default "";
+}
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/SubjectParam.java b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/SubjectParam.java
new file mode 100644
index 0000000..8ff4026
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/java/org/apache/tomee/chatterbox/imap/api/SubjectParam.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.api;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface SubjectParam {
+ String value() default "";
+}
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/resources/META-INF/LICENSE b/chatterbox-imap/chatterbox-imap-api/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-imap/chatterbox-imap-api/src/main/resources/META-INF/NOTICE b/chatterbox-imap/chatterbox-imap-api/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..4142ceb
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-api/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+IMAP Connector :: API
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-imap/chatterbox-imap-impl/pom.xml b/chatterbox-imap/chatterbox-imap-impl/pom.xml
new file mode 100644
index 0000000..49bb4e5
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-impl/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-imap-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-imap-impl</artifactId>
+ <packaging>jar</packaging>
+ <name>Chatterbox :: IMAP :: Resource Adapter Implementation</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-imap-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapActivationSpec.java b/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapActivationSpec.java
new file mode 100644
index 0000000..06845d7
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapActivationSpec.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.imap.adapter;
+
+import org.apache.tomee.chatterbox.imap.api.MailListener;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.Activation;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.InvalidPropertyException;
+import javax.resource.spi.ResourceAdapter;
+
+@Activation(messageListeners = MailListener.class)
+public class ImapActivationSpec implements ActivationSpec {
+
+ private ResourceAdapter resourceAdapter;
+ private Class beanClass;
+ private String folder;
+
+ public Class getBeanClass() {
+ return beanClass;
+ }
+
+ public void setBeanClass(Class beanClass) {
+ this.beanClass = beanClass;
+ }
+
+ public String getFolder() {
+ return folder;
+ }
+
+ public void setFolder(String folder) {
+ this.folder = folder;
+ }
+
+ @Override
+ public void validate() throws InvalidPropertyException {
+ }
+
+ @Override
+ public ResourceAdapter getResourceAdapter() {
+ return resourceAdapter;
+ }
+
+ @Override
+ public void setResourceAdapter(ResourceAdapter ra) throws ResourceException {
+ this.resourceAdapter = ra;
+ }
+}
diff --git a/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapCheckThread.java b/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapCheckThread.java
new file mode 100644
index 0000000..9f784bf
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapCheckThread.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.adapter;
+
+import javax.mail.AuthenticationFailedException;
+import javax.mail.FetchProfile;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.search.FlagTerm;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class ImapCheckThread extends Thread {
+
+ private static final Logger LOGGER = Logger.getLogger(ImapCheckThread.class.getName());
+
+ private final ImapResourceAdapter resourceAdapter;
+ private final Session session;
+ private final AtomicBoolean stopped = new AtomicBoolean(false);
+
+ public ImapCheckThread(ImapResourceAdapter resourceAdapter) {
+ this.resourceAdapter = resourceAdapter;
+ final Properties properties = System.getProperties();
+ session = Session.getDefaultInstance(properties, null);
+ try {
+ // Test the connection
+ connect(session, resourceAdapter);
+ } catch (AuthenticationFailedException e) {
+ if ("imap.gmail.com".equals(resourceAdapter.getHost())) {
+ LOGGER.log(Level.SEVERE, "Failed to Connect " + resourceAdapter + " Ensure 'access to less secure apps' is turned on in your gmail account", e);
+ } else {
+ LOGGER.log(Level.SEVERE, "Failed to Connect " + resourceAdapter, e);
+ }
+ } catch (MessagingException e) {
+ LOGGER.log(Level.SEVERE, "Failed to Connect " + resourceAdapter, e);
+ }
+ }
+
+ private static Store connect(Session session, ImapResourceAdapter resourceAdapter) throws MessagingException {
+ final Store store = session.getStore(resourceAdapter.getProtocol());
+ store.connect(resourceAdapter.getHost(), resourceAdapter.getPort(), resourceAdapter.getUsername(), resourceAdapter.getPassword());
+ return store;
+ }
+
+ @Override
+ public void run() {
+ while (!stopped.get()) {
+ try {
+ final Store store = connect(session, resourceAdapter);
+ processFolder(store, "inbox");
+ } catch (MessagingException e) {
+ LOGGER.log(Level.WARNING, String.format("Failed to Connect %s %s: %s",
+ resourceAdapter, e.getClass().getName(), e.getMessage()));
+ }
+
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ }
+
+ private void processFolder(Store store, String folderName) throws MessagingException {
+ final Folder folder = store.getFolder(folderName);
+ folder.open(Folder.READ_WRITE);
+
+ final Message[] messages = folder.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
+
+ final FetchProfile fp = new FetchProfile();
+ fp.add(FetchProfile.Item.ENVELOPE);
+ fp.add(FetchProfile.Item.CONTENT_INFO);
+ folder.fetch(messages, fp);
+
+ for (final Message message : messages) {
+ message.setFlag(Flags.Flag.SEEN, true);
+ resourceAdapter.process(message);
+ }
+ }
+
+ public void cancel() {
+ stopped.set(true);
+ }
+}
diff --git a/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapResourceAdapter.java b/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapResourceAdapter.java
new file mode 100644
index 0000000..c4bb7f0
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/ImapResourceAdapter.java
@@ -0,0 +1,495 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.adapter;
+
+import org.apache.tomee.chatterbox.imap.api.Body;
+import org.apache.tomee.chatterbox.imap.api.BodyParam;
+import org.apache.tomee.chatterbox.imap.api.From;
+import org.apache.tomee.chatterbox.imap.api.FromParam;
+import org.apache.tomee.chatterbox.imap.api.InvokeAllMatches;
+import org.apache.tomee.chatterbox.imap.api.Subject;
+import org.apache.tomee.chatterbox.imap.api.SubjectParam;
+import org.tomitribe.util.Longs;
+import org.tomitribe.util.editor.Converter;
+import org.tomitribe.util.hash.XxHash64;
+
+import javax.mail.Address;
+import javax.mail.BodyPart;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.resource.ResourceException;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.BootstrapContext;
+import javax.resource.spi.ConfigProperty;
+import javax.resource.spi.Connector;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterInternalException;
+import javax.resource.spi.endpoint.MessageEndpoint;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.transaction.xa.XAResource;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+@Connector(description = "IMAP ResourceAdapter", displayName = "IMAP ResourceAdapter", eisType = "IMAP Adapter", version = "1.0")
+public class ImapResourceAdapter implements ResourceAdapter {
+
+ private static final Logger LOGGER = Logger.getLogger(ImapResourceAdapter.class.getName());
+
+ final Map<ImapActivationSpec, EndpointTarget> targets = new ConcurrentHashMap<>();
+
+ private ImapCheckThread worker;
+
+ @ConfigProperty
+ private String host;
+
+ @ConfigProperty(defaultValue = "993")
+ private Integer port;
+
+ @ConfigProperty
+ private String username;
+
+ @ConfigProperty
+ private String password;
+
+ @ConfigProperty(defaultValue = "imaps")
+ private String protocol;
+
+ @ConfigProperty(defaultValue = "FINE")
+ private String deliveryLogLevel;
+
+ private Level level;
+
+ private static Object[] getValues(final Method method, final String sender, final String subject, final String message) {
+
+ if (method == null) {
+ return null;
+ }
+
+ final Parameter[] parameters = method.getParameters();
+ if (parameters.length == 0) {
+ return new Object[0];
+ }
+
+ final Template senderTemplate = getTemplate(method.getAnnotation(From.class));
+ final Map<String, List<String>> senderParamValues = new HashMap<>();
+ if (senderTemplate != null) {
+ senderTemplate.match(sender, senderParamValues);
+ }
+
+ final Template messageTextTemplate = getTemplate(method.getAnnotation(Body.class));
+ final Map<String, List<String>> messageTextParamValues = new HashMap<>();
+ if (messageTextTemplate != null) {
+ messageTextTemplate.match(message, messageTextParamValues);
+ }
+
+ final Template subjectTemplate = getTemplate(method.getAnnotation(Subject.class));
+ final Map<String, List<String>> subjectParamValues = new HashMap<>();
+ if (subjectTemplate != null) {
+ subjectTemplate.match(subject, subjectParamValues);
+ }
+
+ final Object[] values = new Object[parameters.length];
+
+ for (int i = 0; i < parameters.length; i++) {
+ final Parameter parameter = parameters[i];
+
+ values[i] = null;
+
+ if (parameter.isAnnotationPresent(FromParam.class)) {
+ final FromParam senderParam = parameter.getAnnotation(FromParam.class);
+ if (senderParam.value() == null || senderParam.value().length() == 0) {
+ values[i] = Converter.convert(sender, parameter.getType(), null);
+ } else {
+ final List<String> paramValues = senderParamValues.get(senderParam.value());
+ final String paramValue = paramValues == null || paramValues.size() == 0 ? null : paramValues.get(0);
+ values[i] = Converter.convert(paramValue, parameter.getType(), null);
+ }
+ }
+
+ if (parameter.isAnnotationPresent(BodyParam.class)) {
+ final BodyParam messageTextParam = parameter.getAnnotation(BodyParam.class);
+ if (messageTextParam.value() == null || messageTextParam.value().length() == 0) {
+ values[i] = Converter.convert(message, parameter.getType(), null);
+ } else {
+ final List<String> paramValues = messageTextParamValues.get(messageTextParam.value());
+ final String paramValue = paramValues == null || paramValues.size() == 0 ? null : paramValues.get(0);
+ values[i] = Converter.convert(paramValue, parameter.getType(), null);
+ }
+ }
+
+ if (parameter.isAnnotationPresent(SubjectParam.class)) {
+ final SubjectParam subjectParam = parameter.getAnnotation(SubjectParam.class);
+ if (subjectParam.value() == null || subjectParam.value().length() == 0) {
+ values[i] = Converter.convert(subject, parameter.getType(), null);
+ } else {
+ final List<String> paramValues = messageTextParamValues.get(subjectParam.value());
+ final String paramValue = paramValues == null || paramValues.size() == 0 ? null : paramValues.get(0);
+ values[i] = Converter.convert(paramValue, parameter.getType(), null);
+ }
+ }
+ }
+
+ return values;
+ }
+
+ private static Template getTemplate(final Annotation annotation) {
+ if (annotation == null) {
+ return null;
+ }
+
+ try {
+
+ final Method patternMethod = annotation.getClass().getMethod("value");
+ if (patternMethod == null) {
+ return null;
+ }
+
+ if (!String.class.equals(patternMethod.getReturnType())) {
+ return null;
+ }
+
+ final String pattern = (String) patternMethod.invoke(annotation);
+ return new Template(pattern);
+ } catch (final Exception e) {
+ // ignore
+ }
+
+ return null;
+ }
+
+ private static String getMessageText(final Message message) {
+ try {
+ if (message instanceof MimeMessage) {
+ final MimeMessage m = (MimeMessage) message;
+ Object contentObject = m.getContent();
+ if (contentObject instanceof Multipart) {
+ BodyPart clearTextPart = null;
+
+ Multipart content = (Multipart) contentObject;
+ int count = content.getCount();
+ for (int i = 0; i < count; i++) {
+ BodyPart part = content.getBodyPart(i);
+ if (part.isMimeType("text/plain")) {
+ clearTextPart = part;
+ break;
+ }
+ }
+
+ if (clearTextPart != null) {
+ return (String) clearTextPart.getContent();
+ }
+
+ } else if (contentObject instanceof String) {
+ return (String) contentObject;
+ } else {
+ LOGGER.log(Level.WARNING, "Unable to get message text");
+ return "";
+ }
+ }
+ } catch (IOException | MessagingException e) {
+ LOGGER.log(Level.WARNING, "Unable to get message text");
+ }
+
+ return "";
+ }
+
+ public void start(BootstrapContext bootstrapContext) throws ResourceAdapterInternalException {
+ level = Level.parse(deliveryLogLevel);
+ LOGGER.info("Starting " + this);
+ worker = new ImapCheckThread(this);
+ worker.start();
+ }
+
+ public void stop() {
+ LOGGER.info("Stopping " + this);
+ worker.cancel();
+ }
+
+ public void endpointActivation(final MessageEndpointFactory messageEndpointFactory, final ActivationSpec activationSpec)
+ throws ResourceException {
+ final ImapActivationSpec imapActivationSpec = (ImapActivationSpec) activationSpec;
+ final MessageEndpoint messageEndpoint = messageEndpointFactory.createEndpoint(null);
+
+ final Class<?> endpointClass = imapActivationSpec.getBeanClass() != null ? imapActivationSpec
+ .getBeanClass() : messageEndpointFactory.getEndpointClass();
+
+ final EndpointTarget target = new EndpointTarget(messageEndpoint, endpointClass);
+ targets.put(imapActivationSpec, target);
+
+ }
+
+ public void endpointDeactivation(final MessageEndpointFactory messageEndpointFactory, final ActivationSpec activationSpec) {
+ final ImapActivationSpec imapActivationSpec = (ImapActivationSpec) activationSpec;
+
+ final EndpointTarget endpointTarget = targets.get(imapActivationSpec);
+ if (endpointTarget == null) {
+ throw new IllegalStateException("No EndpointTarget to undeploy for ActivationSpec " + activationSpec);
+ }
+
+ endpointTarget.messageEndpoint.release();
+ }
+
+ public XAResource[] getXAResources(ActivationSpec[] activationSpecs) throws ResourceException {
+ return new XAResource[0];
+ }
+
+ public void process(final Message message) {
+ final Collection<EndpointTarget> endpoints = targets.values();
+ for (final EndpointTarget endpoint : endpoints) {
+ endpoint.invoke(message);
+ }
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public Integer getPort() {
+ return port;
+ }
+
+ public void setPort(Integer port) {
+ this.port = port;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ @Override
+ public String toString() {
+ return "ImapResourceAdapter{" +
+ "host='" + host + '\'' +
+ ", port=" + port +
+ ", username='" + username + '\'' +
+ ", password='" + Longs.toHex(XxHash64.hash(password)) + '\'' +
+ ", protocol='" + protocol + '\'' +
+ '}';
+ }
+
+ private static class Email {
+ private final String sent;
+ private final String to;
+ private final String from;
+ private final String subject;
+
+ private Email(final Message message) throws MessagingException {
+ final Address[] recipients = message.getRecipients(Message.RecipientType.TO);
+ this.to = recipients[0].toString();
+ this.from = message.getFrom()[0].toString();
+ this.sent = format(message.getSentDate());
+ this.subject = message.getSubject();
+ }
+
+ private String format(Date sentDate) {
+ final SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
+ return simpleDateFormat.format(sentDate);
+ }
+
+ @Override
+ public String toString() {
+ return "Email{" +
+ "sent='" + sent + '\'' +
+ ", to='" + to + '\'' +
+ ", from='" + from + '\'' +
+ ", subject='" + subject + '\'' +
+ '}';
+ }
+ }
+
+ public class EndpointTarget {
+ private final MessageEndpoint messageEndpoint;
+ private final Class<?> clazz;
+
+ public EndpointTarget(final MessageEndpoint messageEndpoint, final Class<?> clazz) {
+ this.messageEndpoint = messageEndpoint;
+ this.clazz = clazz;
+ }
+
+ public void invoke(Message message) {
+
+ // Wrapper for convenient logging
+ final Email email;
+ try {
+ email = new Email(message);
+ } catch (MessagingException e) {
+ throw new IllegalStateException(e);
+ }
+
+ // find matching method(s)
+
+ final List<Method> matchingMethods =
+ Arrays.asList(clazz.getDeclaredMethods())
+ .stream()
+ .sorted((m1, m2) -> m1.toString().compareTo(m2.toString()))
+ .filter(this::isPublic)
+ .filter(this::isNotFinal)
+ .filter(this::isNotAbstract)
+ .filter(m -> filterSender(message, m))
+ .filter(m -> filterSubject(message, m))
+ .filter(m -> filterMessage(message, m))
+ .collect(Collectors.toList());
+
+ if (matchingMethods == null || matchingMethods.size() == 0) {
+ LOGGER.log(Level.INFO, "No method to match " + email);
+ return;
+ }
+
+ if (this.clazz.isAnnotationPresent(InvokeAllMatches.class)) {
+ for (final Method method : matchingMethods) {
+ LOGGER.log(level, "Invoking method " + method.toString() + " for " + email);
+ try {
+ invoke(method, InternetAddress.toString(message.getFrom()),
+ message.getSubject(),
+ getMessageText(message));
+ } catch (MessagingException e) {
+ LOGGER.log(Level.SEVERE, "Unable to invoke method " + method.toString() + " for " + email);
+ }
+ }
+ } else {
+ final Method method = matchingMethods.get(0);
+ LOGGER.log(level, "Invoking method " + method.toString() + " for " + email);
+ try {
+ invoke(method, InternetAddress.toString(message.getFrom()),
+ message.getSubject(),
+ getMessageText(message));
+ } catch (MessagingException e) {
+ LOGGER.log(Level.SEVERE, "Unable to invoke method " + method.toString() + " for " + email);
+ }
+ }
+ }
+
+ private boolean filterMessage(final Message message, final Method m) {
+ try {
+ final String messageBody = message.getContent().toString();
+
+ return !m.isAnnotationPresent(Body.class) || "".equals(m.getAnnotation(Body.class).value())
+ || templateMatches(m.getAnnotation(Body.class).value(), messageBody);
+
+ } catch (IOException | MessagingException e) {
+ return false;
+ }
+ }
+
+ private boolean filterSender(final Message message, final Method m) {
+ try {
+ final String sender = InternetAddress.toString(message.getFrom());
+
+ return !m.isAnnotationPresent(From.class) || "".equals(m.getAnnotation(From.class).value())
+ || templateMatches(m.getAnnotation(From.class).value(), sender);
+
+ } catch (MessagingException e) {
+ return false;
+ }
+ }
+
+ private boolean filterSubject(final Message message, final Method m) {
+ try {
+ final String subject = message.getSubject();
+
+ return !m.isAnnotationPresent(Subject.class) || "".equals(m.getAnnotation(Subject.class).value())
+ || templateMatches(m.getAnnotation(Subject.class).value(), subject);
+
+ } catch (MessagingException e) {
+ return false;
+ }
+ }
+
+ private boolean templateMatches(final String pattern, final String input) {
+ try {
+ if (Pattern.matches(pattern, input)) {
+ return true;
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+
+ final Template template = new Template(pattern);
+ final Map<String, List<String>> values = new HashMap<>();
+ return template.match(input, values);
+ }
+
+ private boolean isPublic(final Method m) {
+ return Modifier.isPublic(m.getModifiers());
+ }
+
+ private boolean isNotAbstract(final Method m) {
+ return !Modifier.isAbstract(m.getModifiers());
+ }
+
+ private boolean isNotFinal(final Method m) {
+ return !Modifier.isFinal(m.getModifiers());
+ }
+
+ private void invoke(final Method method, final String sender, final String subject, final String message) {
+ try {
+ try {
+ messageEndpoint.beforeDelivery(method);
+ final Object[] values = getValues(method, sender, subject, message);
+ method.invoke(messageEndpoint, values);
+ } finally {
+ messageEndpoint.afterDelivery();
+ }
+ } catch (final NoSuchMethodException | ResourceException | IllegalAccessException | InvocationTargetException e) {
+ LOGGER.log(Level.SEVERE, "Unable to call method: " + method.toString());
+ }
+ }
+ }
+}
diff --git a/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/Template.java b/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/Template.java
new file mode 100644
index 0000000..8a17ab6
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-impl/src/main/java/org/apache/tomee/chatterbox/imap/adapter/Template.java
@@ -0,0 +1,387 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.imap.adapter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Template {
+
+ public static final String LIMITED_REGEX_SUFFIX = "(/.*)?";
+ public static final String FINAL_MATCH_GROUP = "FINAL_MATCH_GROUP";
+ private static final String DEFAULT_PATH_VARIABLE_REGEX = "([^/]+?)";
+ private static final String CHARACTERS_TO_ESCAPE = ".*+$()";
+
+ private final String template;
+ private final List<String> variables = new ArrayList<String>();
+ private final List<String> customVariables = new ArrayList<String>();
+ private final Pattern templateRegexPattern;
+ private final String literals;
+ private final List<UriChunk> uriChunks;
+
+ public Template(final String theTemplate) {
+ template = theTemplate;
+ final StringBuilder literalChars = new StringBuilder();
+ final StringBuilder patternBuilder = new StringBuilder();
+ final CurlyBraceTokenizer tok = new CurlyBraceTokenizer(template);
+ uriChunks = new ArrayList<>();
+ while (tok.hasNext()) {
+ final String templatePart = tok.next();
+ final UriChunk chunk = UriChunk.createUriChunk(templatePart);
+ uriChunks.add(chunk);
+ if (chunk instanceof Literal) {
+ final String substr = escapeCharacters(chunk.getValue());
+ literalChars.append(substr);
+ patternBuilder.append(substr);
+ } else if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ variables.add(var.getName());
+ if (var.getPattern() != null) {
+ customVariables.add(var.getName());
+ patternBuilder.append('(');
+ patternBuilder.append(var.getPattern());
+ patternBuilder.append(')');
+ } else {
+ patternBuilder.append(DEFAULT_PATH_VARIABLE_REGEX);
+ }
+ }
+ }
+ literals = literalChars.toString();
+
+ final int endPos = patternBuilder.length() - 1;
+ final boolean endsWithSlash = (endPos >= 0) && patternBuilder.charAt(endPos) == '/';
+ if (endsWithSlash) {
+ patternBuilder.deleteCharAt(endPos);
+ }
+ patternBuilder.append(LIMITED_REGEX_SUFFIX);
+
+ templateRegexPattern = Pattern.compile(patternBuilder.toString());
+ }
+
+ private static String escapeCharacters(final String expression) {
+ final StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < expression.length(); i++) {
+ final char ch = expression.charAt(i);
+ sb.append(isReservedCharacter(ch) ? "\\" + ch : ch);
+ }
+ return sb.toString();
+ }
+
+ private static boolean isReservedCharacter(final char ch) {
+ return CHARACTERS_TO_ESCAPE.indexOf(ch) != -1;
+ }
+
+ public String getLiteralChars() {
+ return literals;
+ }
+
+ public String getValue() {
+ return template;
+ }
+
+ public String getPatternValue() {
+ return templateRegexPattern.toString();
+ }
+
+ public List<String> getVariables() {
+ return Collections.unmodifiableList(variables);
+ }
+
+ public List<String> getCustomVariables() {
+ return Collections.unmodifiableList(customVariables);
+ }
+
+ public boolean match(final String uri, final Map<String, List<String>> templateVariableToValue) {
+
+ if (uri == null) {
+ return (templateRegexPattern == null);
+ }
+
+ if (templateRegexPattern == null) {
+ return false;
+ }
+
+ Matcher m = templateRegexPattern.matcher(uri);
+ if (!m.matches()) {
+ return false;
+ }
+
+ // Assign the matched template values to template variables
+ final int groupCount = m.groupCount();
+
+ int i = 1;
+ for (final String name : variables) {
+ while (i <= groupCount) {
+ final String value = m.group(i++);
+ if ((value == null || value.length() == 0 && i < groupCount)
+ && variables.size() + 1 < groupCount) {
+ continue;
+ }
+
+ if (templateVariableToValue.get(name) == null) {
+ templateVariableToValue.put(name, new ArrayList<>());
+ }
+
+ templateVariableToValue.get(name).add(value);
+ break;
+ }
+ }
+ // The right hand side value, might be used to further resolve
+ // sub-resources.
+
+ String finalGroup = m.group(groupCount);
+ if (finalGroup == null) {
+ finalGroup = "";
+ }
+
+ templateVariableToValue.put(FINAL_MATCH_GROUP, Collections.singletonList(finalGroup));
+ return true;
+ }
+
+ public String substitute(final List<String> values) throws IllegalArgumentException {
+ if (values == null) {
+ throw new IllegalArgumentException("values is null");
+ }
+ final Iterator<String> iter = values.iterator();
+ final StringBuilder sb = new StringBuilder();
+ for (final UriChunk chunk : uriChunks) {
+ if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ if (iter.hasNext()) {
+ final String value = iter.next();
+ if (!var.matches(value)) {
+ throw new IllegalArgumentException("Value '" + value + "' does not match variable "
+ + var.getName() + " with value "
+ + var.getPattern());
+ }
+ sb.append(value);
+ } else {
+ sb.append(var);
+ }
+ } else {
+ sb.append(chunk);
+ }
+ }
+ return sb.toString();
+ }
+
+ String substitute(final Map<String, ?> valuesMap) throws IllegalArgumentException {
+ return this.substitute(valuesMap, Collections.<String>emptySet(), false);
+ }
+
+ public String substitute(final Map<String, ?> valuesMap,
+ final Set<String> encodePathSlashVars,
+ final boolean allowUnresolved) throws IllegalArgumentException {
+ if (valuesMap == null) {
+ throw new IllegalArgumentException("valuesMap is null");
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (final UriChunk chunk : uriChunks) {
+ if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ final Object value = valuesMap.get(var.getName());
+ if (value != null) {
+ String sval = value.toString();
+ if (!var.matches(sval)) {
+ throw new IllegalArgumentException("Value '" + sval + "' does not match variable "
+ + var.getName() + " with value "
+ + var.getPattern());
+ }
+ if (encodePathSlashVars.contains(var.getName())) {
+ sval = sval.replaceAll("/", "%2F");
+ }
+ sb.append(sval);
+ } else if (allowUnresolved) {
+ sb.append(chunk);
+ } else {
+ throw new IllegalArgumentException("Template variable " + var.getName()
+ + " has no matching value");
+ }
+ } else {
+ sb.append(chunk);
+ }
+ }
+ return sb.toString();
+ }
+
+ private abstract static class UriChunk {
+ public static UriChunk createUriChunk(final String uriChunk) {
+ if (uriChunk == null || "".equals(uriChunk)) {
+ throw new IllegalArgumentException("uriChunk is empty");
+ }
+ UriChunk uriChunkRepresentation = Variable.create(uriChunk);
+ if (uriChunkRepresentation == null) {
+ uriChunkRepresentation = Literal.create(uriChunk);
+ }
+ return uriChunkRepresentation;
+ }
+
+ public abstract String getValue();
+
+ @Override
+ public String toString() {
+ return getValue();
+ }
+ }
+
+ private static final class Literal extends UriChunk {
+ private String value;
+
+ private Literal() {
+ // empty constructor
+ }
+
+ public static Literal create(final String uriChunk) {
+ if (uriChunk == null || "".equals(uriChunk)) {
+ throw new IllegalArgumentException("uriChunk is empty");
+ }
+ final Literal literal = new Literal();
+ literal.value = uriChunk;
+ return literal;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ }
+
+ private static final class Variable extends UriChunk {
+ private static final Pattern VARIABLE_PATTERN = Pattern.compile("(\\w[-\\w\\.]*[ ]*)(\\:(.+))?");
+ private String name;
+ private Pattern pattern;
+
+ private Variable() {
+ // empty constructor
+ }
+
+ public static Variable create(String uriChunk) {
+ final Variable newVariable = new Variable();
+ if (uriChunk == null || "".equals(uriChunk)) {
+ return null;
+ }
+ if (CurlyBraceTokenizer.insideBraces(uriChunk)) {
+ uriChunk = CurlyBraceTokenizer.stripBraces(uriChunk).trim();
+ final Matcher matcher = VARIABLE_PATTERN.matcher(uriChunk);
+ if (matcher.matches()) {
+ newVariable.name = matcher.group(1).trim();
+ if (matcher.group(2) != null && matcher.group(3) != null) {
+ final String patternExpression = matcher.group(3).trim();
+ newVariable.pattern = Pattern.compile(patternExpression);
+ }
+ return newVariable;
+ }
+ }
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPattern() {
+ return pattern != null ? pattern.pattern() : null;
+ }
+
+ public boolean matches(final String value) {
+ if (pattern == null) {
+ return true;
+ } else {
+ return pattern.matcher(value).matches();
+ }
+ }
+
+ @Override
+ public String getValue() {
+ if (pattern != null) {
+ return "{" + name + ":" + pattern + "}";
+ } else {
+ return "{" + name + "}";
+ }
+ }
+ }
+
+ static class CurlyBraceTokenizer {
+
+ private final List<String> tokens = new ArrayList<String>();
+ private int tokenIdx;
+
+ CurlyBraceTokenizer(final String string) {
+ boolean outside = true;
+ int level = 0;
+ int lastIdx = 0;
+ int idx;
+ for (idx = 0; idx < string.length(); idx++) {
+ if (string.charAt(idx) == '{') {
+ if (outside) {
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx));
+ }
+ lastIdx = idx;
+ outside = false;
+ } else {
+ level++;
+ }
+ } else if (string.charAt(idx) == '}' && !outside) {
+ if (level > 0) {
+ level--;
+ } else {
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx + 1));
+ }
+ lastIdx = idx + 1;
+ outside = true;
+ }
+ }
+ }
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx));
+ }
+ }
+
+ public static boolean insideBraces(final String token) {
+ return token.charAt(0) == '{' && token.charAt(token.length() - 1) == '}';
+ }
+
+ public static String stripBraces(final String token) {
+ if (insideBraces(token)) {
+ return token.substring(1, token.length() - 1);
+ } else {
+ return token;
+ }
+ }
+
+ public boolean hasNext() {
+ return tokens.size() > tokenIdx;
+ }
+
+ public String next() {
+ if (hasNext()) {
+ return tokens.get(tokenIdx++);
+ } else {
+ throw new IllegalStateException("no more elements");
+ }
+ }
+ }
+}
diff --git a/chatterbox-imap/chatterbox-imap-impl/src/main/resources/META-INF/LICENSE b/chatterbox-imap/chatterbox-imap-impl/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-impl/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-imap/chatterbox-imap-impl/src/main/resources/META-INF/NOTICE b/chatterbox-imap/chatterbox-imap-impl/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..4f19e05
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-impl/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+IMAP Connector :: Resource Adapter Implementation
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-imap/chatterbox-imap-rar/pom.xml b/chatterbox-imap/chatterbox-imap-rar/pom.xml
new file mode 100644
index 0000000..52070e0
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-rar/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-imap-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-imap-rar</artifactId>
+ <packaging>rar</packaging>
+ <name>Chatterbox :: IMAP :: Resource Adapter</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-imap-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/LICENSE b/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/NOTICE b/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/NOTICE
new file mode 100644
index 0000000..ec06cd4
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/NOTICE
@@ -0,0 +1,6 @@
+IMAP Connector :: Resource Adapter
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/ra.xml b/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/ra.xml
new file mode 100644
index 0000000..8939a8f
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-rar/src/main/rar/META-INF/ra.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<connector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/connector_1_7.xsd"
+ version="1.7">
+ <description>IMAP ResourceAdapter</description>
+ <display-name>IMAP ResourceAdapter</display-name>
+ <eis-type>IMAP Adapter</eis-type>
+ <resourceadapter-version>1.0</resourceadapter-version>
+ <license>
+ <license-required>false</license-required>
+ </license>
+ <resourceadapter>
+ <resourceadapter-class>org.apache.tomee.chatterbox.imap.adapter.ImapResourceAdapter</resourceadapter-class>
+ <outbound-resourceadapter>
+ <transaction-support>NoTransaction</transaction-support>
+ <reauthentication-support>false</reauthentication-support>
+ </outbound-resourceadapter>
+ <inbound-resourceadapter>
+ <messageadapter>
+ <messagelistener>
+ <messagelistener-type>MailListener</messagelistener-type>
+ <activationspec>
+ <activationspec-class>org.apache.tomee.chatterbox.imap.adapter.ImapActivationSpec</activationspec-class>
+ </activationspec>
+ </messagelistener>
+ </messageadapter>
+ </inbound-resourceadapter>
+ </resourceadapter>
+</connector>
+
diff --git a/chatterbox-imap/chatterbox-imap-sample-war/pom.xml b/chatterbox-imap/chatterbox-imap-sample-war/pom.xml
new file mode 100644
index 0000000..5a60d58
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-sample-war/pom.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-imap-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-imap-sample-war</artifactId>
+ <packaging>war</packaging>
+ <name>Chatterbox :: IMAP :: Sample</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-imap-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>apache-tomee</artifactId>
+ <version>${version.tomee}</version>
+ <classifier>plus</classifier>
+ <type>zip</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.18.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.6</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.openejb.maven</groupId>
+ <artifactId>tomee-maven-plugin</artifactId>
+ <version>1.7.2</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.openejb.maven</groupId>
+ <artifactId>tomee-maven-plugin</artifactId>
+ <configuration>
+ <tomeeClassifier>plus</tomeeClassifier>
+ <context>ROOT</context>
+ <libs>
+ <lib>remove:geronimo-javamail_1.4_mail</lib>
+ <lib>org.apache.tomee.chatterbox:chatterbox-imap-api:${project.version}</lib>
+ <lib>org.apache.geronimo.javamail:geronimo-javamail_1.4_mail:1.9.0-alpha-2</lib>
+ </libs>
+ <apps>
+ <app>org.apache.tomee.chatterbox:chatterbox-imap-rar:${project.version}:rar</app>
+ </apps>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/chatterbox-imap/chatterbox-imap-sample-war/src/main/java/org/superbiz/imap/InboxReader.java b/chatterbox-imap/chatterbox-imap-sample-war/src/main/java/org/superbiz/imap/InboxReader.java
new file mode 100644
index 0000000..89d5fab
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-sample-war/src/main/java/org/superbiz/imap/InboxReader.java
@@ -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.
+ */
+package org.superbiz.imap;
+
+import org.apache.tomee.chatterbox.imap.api.BodyParam;
+import org.apache.tomee.chatterbox.imap.api.FromParam;
+import org.apache.tomee.chatterbox.imap.api.MailListener;
+import org.apache.tomee.chatterbox.imap.api.Subject;
+import org.apache.tomee.chatterbox.imap.api.SubjectParam;
+
+import javax.ejb.MessageDriven;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@MessageDriven
+public class InboxReader implements MailListener {
+
+ private static final Logger LOGGER = Logger.getLogger(InboxReader.class.getName());
+
+ @Subject(".*test.*")
+ public void logMessage(@FromParam final String from, @SubjectParam final String subject, @BodyParam final String message) {
+ LOGGER.log(Level.INFO, String.format("Message from: %s, subject: %s", from, subject));
+ LOGGER.log(Level.INFO, String.format("Message body: %s", message));
+ }
+
+}
diff --git a/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/LICENSE b/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/NOTICE b/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..24017b1
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+IMAP Connector :: Sample WAR
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/ejb-jar.xml b/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/ejb-jar.xml
new file mode 100644
index 0000000..e983d25
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-sample-war/src/main/resources/META-INF/ejb-jar.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
+ version="3.1">
+ <display-name>imap-connector-sample-ejb</display-name>
+</ejb-jar>
diff --git a/chatterbox-imap/chatterbox-imap-sample-war/src/main/tomee/conf/tomee.xml b/chatterbox-imap/chatterbox-imap-sample-war/src/main/tomee/conf/tomee.xml
new file mode 100644
index 0000000..889e1d9
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-sample-war/src/main/tomee/conf/tomee.xml
@@ -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.
+ -->
+
+<tomee>
+ <Deployments dir="apps"/>
+ <Resource id="OutgoingMail" type="javax.mail.Session">
+ mail.smtp.host=smtp.gmail.com
+ mail.smtp.port=465
+ mail.transport.protocol=smtps
+ mail.smtp.auth=true
+ </Resource>
+</tomee>
\ No newline at end of file
diff --git a/chatterbox-imap/chatterbox-imap-sample-war/src/main/webapp/index.jsp b/chatterbox-imap/chatterbox-imap-sample-war/src/main/webapp/index.jsp
new file mode 100644
index 0000000..30a9f7c
--- /dev/null
+++ b/chatterbox-imap/chatterbox-imap-sample-war/src/main/webapp/index.jsp
@@ -0,0 +1,24 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+-->
+<%@ page session="false" %>
+<html>
+<body>
+<h1>Hello, world!</h1>
+</body>
+</html>
\ No newline at end of file
diff --git a/chatterbox-imap/pom.xml b/chatterbox-imap/pom.xml
new file mode 100644
index 0000000..47ba1f3
--- /dev/null
+++ b/chatterbox-imap/pom.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-imap-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>0.3-SNAPSHOT</version>
+ <name>Chatterbox :: IMAP</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.arquillian>1.1.1.Final</version.arquillian>
+ <version.shrinkwrap.descriptor>2.0.0-alpha-5</version.shrinkwrap.descriptor>
+ <version.shrinkwrap.shrinkwrap>1.0.1</version.shrinkwrap.shrinkwrap>
+ <version.tomee>1.7.2</version.tomee>
+ <version.openejb>4.7.2</version.openejb>
+ <maven.checkstyle.plugin.version>2.16</maven.checkstyle.plugin.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ <version>1.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <version>7.0</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <modules>
+ <module>chatterbox-imap-api</module>
+ <module>chatterbox-imap-impl</module>
+ <module>chatterbox-imap-rar</module>
+ <module>chatterbox-imap-sample-war</module>
+ </modules>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>reserve-network-port</id>
+ <phase>process-test-classes</phase>
+ <goals>
+ <goal>reserve-network-port</goal>
+ </goals>
+ <configuration>
+ <portNames>
+ <portName>tomee.http.port</portName>
+ <portName>tomee.shutdown.port</portName>
+ </portNames>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <optimize>true</optimize>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/chatterbox-slack/.gitignore b/chatterbox-slack/.gitignore
new file mode 100644
index 0000000..9e544aa
--- /dev/null
+++ b/chatterbox-slack/.gitignore
@@ -0,0 +1,30 @@
+# Java #
+*.class
+*.ser
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# IDEA #
+*.iml
+.idea
+*~
+
+# eclipse specific git ignore
+.project
+.metadata
+.classpath
+.settings/
+
+
+# Maven files #
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.next
+release.properties
+
+# Checkstyle #
+.checkstyle
diff --git a/chatterbox-slack/chatterbox-slack-api/pom.xml b/chatterbox-slack/chatterbox-slack-api/pom.xml
new file mode 100644
index 0000000..b2ffc87
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-api/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-slack-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-slack-api</artifactId>
+ <packaging>jar</packaging>
+ <name>Chatterbox :: Slack :: API</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.arquillian>1.1.1.Final</version.arquillian>
+ <version.shrinkwrap.descriptor>2.0.0-alpha-5</version.shrinkwrap.descriptor>
+ <version.shrinkwrap.shrinkwrap>1.0.1</version.shrinkwrap.shrinkwrap>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/InboundListener.java b/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/InboundListener.java
new file mode 100644
index 0000000..c8588e4
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/InboundListener.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.slack.api;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public interface InboundListener {
+}
diff --git a/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/SlackConnection.java b/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/SlackConnection.java
new file mode 100755
index 0000000..f933400
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/SlackConnection.java
@@ -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.
+ */
+
+package org.apache.tomee.chatterbox.slack.api;
+
+public interface SlackConnection {
+ public void sendMessage(final String channel, final String message);
+
+ public void close();
+}
diff --git a/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/SlackConnectionFactory.java b/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/SlackConnectionFactory.java
new file mode 100755
index 0000000..d352ab4
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-api/src/main/java/org/apache/tomee/chatterbox/slack/api/SlackConnectionFactory.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.slack.api;
+
+import javax.resource.Referenceable;
+import javax.resource.ResourceException;
+import java.io.Serializable;
+
+public interface SlackConnectionFactory extends Serializable, Referenceable {
+ public SlackConnection getConnection() throws ResourceException;
+
+}
diff --git a/chatterbox-slack/chatterbox-slack-api/src/main/resources/META-INF/LICENSE b/chatterbox-slack/chatterbox-slack-api/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-api/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-slack/chatterbox-slack-api/src/main/resources/META-INF/NOTICE b/chatterbox-slack/chatterbox-slack-api/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..c17892d
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-api/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+Slack Connector :: API
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-slack/chatterbox-slack-impl/pom.xml b/chatterbox-slack/chatterbox-slack-impl/pom.xml
new file mode 100644
index 0000000..f7f9143
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-slack-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-slack-impl</artifactId>
+ <packaging>jar</packaging>
+ <name>Chatterbox :: Slack :: Resource Adapter Implementation</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-slack-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>openejb-core</artifactId>
+ <version>${version.openejb}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.github.flowctrl</groupId>
+ <artifactId>slack-api</artifactId>
+ <version>v1.1.0.RELEASE</version>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-crest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-crest-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/Arguments.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/Arguments.java
new file mode 100644
index 0000000..99ea353
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/Arguments.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.slack.adapter;
+
+public final class Arguments {
+ private String[] args;
+
+ Arguments(final String[] strings) {
+ this.args = strings;
+ }
+
+ public String[] get() {
+ return args;
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/ArgumentsParser.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/ArgumentsParser.java
new file mode 100644
index 0000000..8fbadfc
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/ArgumentsParser.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.slack.adapter;
+
+import org.tomitribe.util.IO;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ArgumentsParser {
+
+ private static final char EOF = (char) -1;
+ final List<Arguments> commands = new ArrayList<>();
+ final List<String> result = new ArrayList<>();
+ final InputStream input;
+
+ StringBuilder arg;
+ State state = this::continueBare;
+
+ public ArgumentsParser(final String input) {
+ this(IO.read(input));
+ }
+
+ public ArgumentsParser(final InputStream input) {
+ this.input = input;
+ }
+
+ public static Arguments[] parse(final String line) {
+ final ArgumentsParser parser = new ArgumentsParser(line);
+ return parser.parseArgs();
+ }
+
+ public Arguments[] parseArgs() {
+
+ char c = EOF;
+
+ while ((c = state.read()) != EOF) {
+ if (arg == null) arg = new StringBuilder();
+ arg.append(c);
+ }
+
+ endCommand();
+
+ return commands.toArray(new Arguments[commands.size()]);
+ }
+
+ public void endCommand() {
+ if (arg != null) {
+ result.add(arg.toString());
+ arg.setLength(0);
+ }
+
+ if (!result.isEmpty()) {
+ commands.add(new Arguments(result.toArray(new String[result.size()])));
+ result.clear();
+ }
+ }
+
+ private char continueBare() {
+
+ final char read = read();
+
+ // Skip passed any white space
+ if (isSeparator(read)) {
+
+ // If we were reading an arg, close it
+ if (arg != null) {
+ result.add(arg.toString());
+ arg = null;
+ }
+
+ return continueBare();
+ }
+
+ if ('|' == read) {
+ endCommand();
+ return continueBare();
+ }
+
+ // We've found something not whitespace
+ if (EOF != read && arg == null) {
+ arg = new StringBuilder();
+ }
+
+ if ('\'' == read) return next(this::inSingleQuotes);
+ if ('\"' == read) return next(this::inDoubleQuotes);
+ if ('\\' == read) return next(this::escape);
+
+ return read;
+ }
+
+ private boolean isSeparator(char read) {
+ switch (read) {
+ case ' ':
+ case '\t':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private char inSingleQuotes() {
+ final char read = read();
+ if ('\'' == read) return next(this::continueBare);
+ return read;
+ }
+
+ private char inDoubleQuotes() {
+ final char read = read();
+ if ('\"' == read) return next(this::continueBare);
+ if ('\\' == read) return next(this::escapeInDoubleQuotes);
+ return read;
+ }
+
+ private char escape() {
+ return use(read(), this::continueBare);
+ }
+
+ private char escapeInDoubleQuotes() {
+ final char read = read();
+ switch (read) {
+ case '\"':
+ case '$':
+ case '\\':
+ case '`':
+ return use(read, this::inDoubleQuotes);
+ default:
+ }
+
+ return next(flush()
+ .state(this::backslash)
+ .state(() -> read)
+ .state(this::inDoubleQuotes)
+ .states());
+ }
+
+ private char next(final State state) {
+ this.state = state;
+ return state.read();
+ }
+
+ private char use(char current, final State next) {
+ this.state = next;
+ return current;
+ }
+
+ private char read() {
+ try {
+ return (char) input.read();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public Seq flush() {
+ return new Seq();
+ }
+
+ private char backslash() {
+ return '\\';
+ }
+
+ public interface State {
+ char read();
+ }
+
+ public class Seq {
+ private final List<State> states = new LinkedList<>();
+
+ public Seq state(State next) {
+ states.add(next);
+ return this;
+ }
+
+ public State states() {
+ final Iterator<State> iterator = states.iterator();
+ return () -> {
+ final State next = iterator.next();
+ if (iterator.hasNext()) return next.read();
+ return next(next);
+ };
+ }
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/SlackActivationSpec.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/SlackActivationSpec.java
new file mode 100644
index 0000000..9c90830
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/SlackActivationSpec.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.slack.adapter;
+
+import org.apache.tomee.chatterbox.slack.api.InboundListener;
+import org.tomitribe.crest.cmds.Cmd;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.Activation;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.InvalidPropertyException;
+import javax.resource.spi.ResourceAdapter;
+import java.util.ArrayList;
+import java.util.List;
+
+@Activation(messageListeners = InboundListener.class)
+public class SlackActivationSpec implements ActivationSpec {
+
+ private ResourceAdapter resourceAdapter;
+ private Class beanClass;
+ private List<Cmd> commands = new ArrayList<Cmd>();
+
+ public List<Cmd> getCommands() {
+ return commands;
+ }
+
+ public Class getBeanClass() {
+ return beanClass;
+ }
+
+ public void setBeanClass(Class beanClass) {
+ this.beanClass = beanClass;
+ }
+
+ @Override
+ public void validate() throws InvalidPropertyException {
+ }
+
+ @Override
+ public ResourceAdapter getResourceAdapter() {
+ return resourceAdapter;
+ }
+
+ @Override
+ public void setResourceAdapter(ResourceAdapter ra) throws ResourceException {
+ this.resourceAdapter = ra;
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/SlackResourceAdapter.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/SlackResourceAdapter.java
new file mode 100644
index 0000000..661785c
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/SlackResourceAdapter.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.slack.adapter;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import flowctrl.integration.slack.SlackClientFactory;
+import flowctrl.integration.slack.rtm.Event;
+import flowctrl.integration.slack.rtm.EventListener;
+import flowctrl.integration.slack.rtm.SlackRealTimeMessagingClient;
+import flowctrl.integration.slack.type.Authentication;
+import flowctrl.integration.slack.type.Presence;
+import flowctrl.integration.slack.webapi.SlackWebApiClient;
+import flowctrl.integration.slack.webapi.method.chats.ChatPostMessageMethod;
+import org.tomitribe.crest.Main;
+import org.tomitribe.crest.cmds.Cmd;
+import org.tomitribe.crest.cmds.processors.Commands;
+import org.tomitribe.crest.cmds.targets.Target;
+import org.tomitribe.crest.environments.Environment;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.BootstrapContext;
+import javax.resource.spi.ConfigProperty;
+import javax.resource.spi.Connector;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterInternalException;
+import javax.resource.spi.endpoint.MessageEndpoint;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.resource.spi.work.Work;
+import javax.resource.spi.work.WorkManager;
+import javax.transaction.xa.XAResource;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Connector(description = "Sample Resource Adapter", displayName = "Sample Resource Adapter", eisType = "Sample Resource Adapter", version = "1.0")
+public class SlackResourceAdapter implements ResourceAdapter, EventListener {
+ final Map<SlackActivationSpec, EndpointTarget> targets = new ConcurrentHashMap<SlackActivationSpec, EndpointTarget>();
+
+ @ConfigProperty
+ private String token;
+
+ private SlackRealTimeMessagingClient slackRealTimeMessagingClient;
+ private SlackWebApiClient webApiClient;
+ private Main main;
+ private WorkManager workManager;
+ private String user;
+ private String userId;
+
+ public void start(BootstrapContext bootstrapContext) throws ResourceAdapterInternalException {
+ workManager = bootstrapContext.getWorkManager();
+ webApiClient = SlackClientFactory.createWebApiClient(token);
+ slackRealTimeMessagingClient = SlackClientFactory.createSlackRealTimeMessagingClient(token);
+
+ final Authentication authentication = webApiClient.auth();
+ user = authentication.getUser();
+ userId = authentication.getUser_id();
+
+ webApiClient.setPresenceUser(Presence.AUTO);
+
+ slackRealTimeMessagingClient.addListener(Event.MESSAGE, this);
+ slackRealTimeMessagingClient.connect();
+ main = new Main();
+ }
+
+ public void stop() {
+ webApiClient.setPresenceUser(Presence.AWAY);
+ }
+
+ public void endpointActivation(final MessageEndpointFactory messageEndpointFactory, final ActivationSpec activationSpec)
+ throws ResourceException {
+ final SlackActivationSpec slackActivationSpec = (SlackActivationSpec) activationSpec;
+
+ workManager.scheduleWork(new Work() {
+
+ @Override
+ public void run() {
+ try {
+ final MessageEndpoint messageEndpoint = messageEndpointFactory.createEndpoint(null);
+
+ final EndpointTarget target = new EndpointTarget(messageEndpoint);
+ final Class<?> endpointClass = slackActivationSpec.getBeanClass() != null ? slackActivationSpec
+ .getBeanClass() : messageEndpointFactory.getEndpointClass();
+
+ target.commands.addAll(Commands.get(endpointClass, target, null).values());
+
+ for (Cmd cmd : target.commands) {
+ main.add(cmd);
+ }
+
+ targets.put(slackActivationSpec, target);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void release() {
+ }
+
+ });
+
+ }
+
+ public void endpointDeactivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) {
+ final SlackActivationSpec telnetActivationSpec = (SlackActivationSpec) activationSpec;
+
+ final EndpointTarget endpointTarget = targets.get(telnetActivationSpec);
+ if (endpointTarget == null) {
+ throw new IllegalStateException("No EndpointTarget to undeploy for ActivationSpec " + activationSpec);
+ }
+
+ final List<Cmd> commands = telnetActivationSpec.getCommands();
+ for (Cmd command : commands) {
+ main.remove(command);
+ }
+
+ endpointTarget.messageEndpoint.release();
+ }
+
+ public XAResource[] getXAResources(ActivationSpec[] activationSpecs) throws ResourceException {
+ return new XAResource[0];
+ }
+
+ public void sendMessage(final String channel, final String message) {
+ ChatPostMessageMethod postMessage = new ChatPostMessageMethod(channel, message);
+ postMessage.setUsername(user);
+ webApiClient.postMessage(postMessage);
+ }
+
+ @Override
+ public void handleMessage(final JsonNode jsonNode) {
+
+ String commandLine = jsonNode.get("text").textValue();
+ final String userPrefix = "<@" + userId + ">";
+ if (!commandLine.startsWith(userPrefix)) {
+ return;
+ }
+
+ // chop off the user: prefix
+ commandLine = commandLine.replaceAll("^" + userPrefix + ":?\\s*", "");
+
+ final String channel = jsonNode.get("channel").textValue();
+
+ String[] args;
+ final Arguments[] arguments = ArgumentsParser.parse(commandLine);
+ if (arguments == null || arguments.length == 0) {
+ args = new String[]{"help"};
+ } else {
+ args = arguments[0].get();
+ }
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ final PrintStream ps = new PrintStream(os);
+ final Environment environment = new Environment() {
+ @Override
+ public PrintStream getOutput() {
+ return ps;
+ }
+
+ @Override
+ public PrintStream getError() {
+ return ps;
+ }
+
+ @Override
+ public InputStream getInput() {
+ return null;
+ }
+
+ @Override
+ public Properties getProperties() {
+ return System.getProperties();
+ }
+ };
+
+ try {
+ main.main(environment, args);
+ } catch (Exception e) {
+ e.printStackTrace(ps);
+ }
+
+ ChatPostMessageMethod postMessage = new ChatPostMessageMethod(channel, new String(os.toByteArray()));
+ postMessage.setUsername(user);
+ webApiClient.postMessage(postMessage);
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(final String token) {
+ this.token = token;
+ }
+
+ private static class EndpointTarget implements Target {
+ private final MessageEndpoint messageEndpoint;
+ private final List<Cmd> commands = new ArrayList<Cmd>();
+
+ public EndpointTarget(MessageEndpoint messageEndpoint) {
+ this.messageEndpoint = messageEndpoint;
+ }
+
+ @Override
+ public Object invoke(Method method, Object... objects)
+ throws InvocationTargetException, IllegalAccessException {
+
+ try {
+ try {
+ messageEndpoint.beforeDelivery(method);
+
+ return method.invoke(messageEndpoint, objects);
+ } finally {
+ messageEndpoint.afterDelivery();
+ }
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ } catch (ResourceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackConnectionFactoryImpl.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackConnectionFactoryImpl.java
new file mode 100755
index 0000000..9de789b
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackConnectionFactoryImpl.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.slack.adapter.out;
+
+import org.apache.tomee.chatterbox.slack.api.SlackConnection;
+import org.apache.tomee.chatterbox.slack.api.SlackConnectionFactory;
+
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import java.util.logging.Logger;
+
+public class SlackConnectionFactoryImpl implements SlackConnectionFactory {
+ private static final long serialVersionUID = 1L;
+
+ private static Logger log = Logger.getLogger(SlackConnectionFactoryImpl.class.getName());
+
+ private Reference reference;
+
+ private SlackManagedConnectionFactory mcf;
+
+ private ConnectionManager connectionManager;
+
+ public SlackConnectionFactoryImpl() {
+
+ }
+
+ public SlackConnectionFactoryImpl(SlackManagedConnectionFactory mcf, ConnectionManager cxManager) {
+ this.mcf = mcf;
+ this.connectionManager = cxManager;
+ }
+
+ @Override
+ public SlackConnection getConnection() throws ResourceException {
+ log.finest("getConnection()");
+ return (SlackConnection) connectionManager.allocateConnection(mcf, null);
+ }
+
+ @Override
+ public Reference getReference() throws NamingException {
+ log.finest("getReference()");
+ return reference;
+ }
+
+ @Override
+ public void setReference(Reference reference) {
+ log.finest("setReference()");
+ this.reference = reference;
+ }
+
+
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackConnectionImpl.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackConnectionImpl.java
new file mode 100755
index 0000000..2a0fe05
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackConnectionImpl.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.slack.adapter.out;
+
+import org.apache.tomee.chatterbox.slack.api.SlackConnection;
+
+import java.util.logging.Logger;
+
+public class SlackConnectionImpl implements SlackConnection {
+ private static Logger log = Logger.getLogger(SlackConnectionImpl.class.getName());
+
+ private SlackManagedConnection mc;
+
+ private SlackManagedConnectionFactory mcf;
+
+ public SlackConnectionImpl(SlackManagedConnection mc, SlackManagedConnectionFactory mcf) {
+ this.mc = mc;
+ this.mcf = mcf;
+ }
+
+ public void sendMessage(final String channel, final String message) {
+ mc.sendMessage(channel, message);
+ }
+
+ public void close() {
+ mc.closeHandle(this);
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnection.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnection.java
new file mode 100755
index 0000000..f88b6e2
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnection.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.slack.adapter.out;
+
+import org.apache.tomee.chatterbox.slack.adapter.SlackResourceAdapter;
+import org.apache.tomee.chatterbox.slack.api.SlackConnection;
+
+import javax.resource.NotSupportedException;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionEvent;
+import javax.resource.spi.ConnectionEventListener;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.LocalTransaction;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionMetaData;
+import javax.security.auth.Subject;
+import javax.transaction.xa.XAResource;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class SlackManagedConnection implements ManagedConnection {
+
+ private static Logger log = Logger.getLogger(SlackManagedConnection.class.getName());
+
+ private PrintWriter logwriter;
+
+ private SlackManagedConnectionFactory mcf;
+
+ private List<ConnectionEventListener> listeners;
+
+ private SlackConnectionImpl connection;
+
+ public SlackManagedConnection(SlackManagedConnectionFactory mcf) {
+ this.mcf = mcf;
+ this.logwriter = null;
+ this.listeners = Collections.synchronizedList(new ArrayList<ConnectionEventListener>(1));
+ this.connection = null;
+ }
+
+ public Object getConnection(Subject subject,
+ ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("getConnection()");
+ connection = new SlackConnectionImpl(this, mcf);
+ return connection;
+ }
+
+ public void associateConnection(Object connection) throws ResourceException {
+ log.finest("associateConnection()");
+
+ if (connection == null)
+ throw new ResourceException("Null connection handle");
+
+ if (!(connection instanceof SlackConnectionImpl))
+ throw new ResourceException("Wrong connection handle");
+
+ this.connection = (SlackConnectionImpl) connection;
+ }
+
+ public void cleanup() throws ResourceException {
+ log.finest("cleanup()");
+ }
+
+ public void destroy() throws ResourceException {
+ log.finest("destroy()");
+ }
+
+ public void addConnectionEventListener(ConnectionEventListener listener) {
+ log.finest("addConnectionEventListener()");
+
+ if (listener == null) {
+ throw new IllegalArgumentException("Listener is null");
+ }
+
+ listeners.add(listener);
+ }
+
+ public void removeConnectionEventListener(ConnectionEventListener listener) {
+ log.finest("removeConnectionEventListener()");
+ if (listener == null)
+ throw new IllegalArgumentException("Listener is null");
+ listeners.remove(listener);
+ }
+
+ void closeHandle(SlackConnection handle) {
+ ConnectionEvent event = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
+ event.setConnectionHandle(handle);
+ for (ConnectionEventListener cel : listeners) {
+ cel.connectionClosed(event);
+ }
+ }
+
+ public PrintWriter getLogWriter() throws ResourceException {
+ log.finest("getLogWriter()");
+ return logwriter;
+ }
+
+ public void setLogWriter(PrintWriter out) throws ResourceException {
+ log.finest("setLogWriter()");
+ logwriter = out;
+ }
+
+ public LocalTransaction getLocalTransaction() throws ResourceException {
+ throw new NotSupportedException("getLocalTransaction() not supported");
+ }
+
+ public XAResource getXAResource() throws ResourceException {
+ throw new NotSupportedException("getXAResource() not supported");
+ }
+
+ public ManagedConnectionMetaData getMetaData() throws ResourceException {
+ log.finest("getMetaData()");
+ return new SlackManagedConnectionMetaData();
+ }
+
+ void sendMessage(final String channel, final String message) {
+ log.finest("sendMessage()");
+
+ final SlackResourceAdapter resourceAdapter = (SlackResourceAdapter) mcf.getResourceAdapter();
+ resourceAdapter.sendMessage(channel, message);
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnectionFactory.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnectionFactory.java
new file mode 100755
index 0000000..3171832
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnectionFactory.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.slack.adapter.out;
+
+import org.apache.tomee.chatterbox.slack.api.SlackConnection;
+import org.apache.tomee.chatterbox.slack.api.SlackConnectionFactory;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionDefinition;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterAssociation;
+import javax.security.auth.Subject;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Logger;
+
+@ConnectionDefinition(connectionFactory = SlackConnectionFactory.class,
+ connectionFactoryImpl = SlackConnectionFactoryImpl.class,
+ connection = SlackConnection.class,
+ connectionImpl = SlackConnectionImpl.class)
+public class SlackManagedConnectionFactory implements ManagedConnectionFactory, ResourceAdapterAssociation {
+
+ private static final long serialVersionUID = 1L;
+
+ private static Logger log = Logger.getLogger(SlackManagedConnectionFactory.class.getName());
+
+ private ResourceAdapter ra;
+
+ private PrintWriter logwriter;
+
+ public SlackManagedConnectionFactory() {
+
+ }
+
+ public Object createConnectionFactory(ConnectionManager cxManager) throws ResourceException {
+ log.finest("createConnectionFactory()");
+ return new SlackConnectionFactoryImpl(this, cxManager);
+ }
+
+ public Object createConnectionFactory() throws ResourceException {
+ throw new ResourceException("This resource adapter doesn't support non-managed environments");
+ }
+
+ public ManagedConnection createManagedConnection(Subject subject,
+ ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("createManagedConnection()");
+ return new SlackManagedConnection(this);
+ }
+
+ public ManagedConnection matchManagedConnections(Set connectionSet,
+ Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("matchManagedConnections()");
+ ManagedConnection result = null;
+ Iterator it = connectionSet.iterator();
+ while (result == null && it.hasNext()) {
+ ManagedConnection mc = (ManagedConnection) it.next();
+ if (mc instanceof SlackManagedConnection) {
+ result = mc;
+ }
+
+ }
+ return result;
+ }
+
+ public PrintWriter getLogWriter() throws ResourceException {
+ log.finest("getLogWriter()");
+ return logwriter;
+ }
+
+ public void setLogWriter(PrintWriter out) throws ResourceException {
+ log.finest("setLogWriter()");
+ logwriter = out;
+ }
+
+ public ResourceAdapter getResourceAdapter() {
+ log.finest("getResourceAdapter()");
+ return ra;
+ }
+
+ public void setResourceAdapter(ResourceAdapter ra) {
+ log.finest("setResourceAdapter()");
+ this.ra = ra;
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnectionMetaData.java b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnectionMetaData.java
new file mode 100755
index 0000000..6b6259b
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/java/org/apache/tomee/chatterbox/slack/adapter/out/SlackManagedConnectionMetaData.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.slack.adapter.out;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnectionMetaData;
+import java.util.logging.Logger;
+
+public class SlackManagedConnectionMetaData implements ManagedConnectionMetaData {
+
+ private static Logger log = Logger.getLogger(SlackManagedConnectionMetaData.class.getName());
+
+ public SlackManagedConnectionMetaData() {
+
+ }
+
+ @Override
+ public String getEISProductName() throws ResourceException {
+ log.finest("getEISProductName()");
+ return null; //TODO
+ }
+
+ @Override
+ public String getEISProductVersion() throws ResourceException {
+ log.finest("getEISProductVersion()");
+ return null; //TODO
+ }
+
+ @Override
+ public int getMaxConnections() throws ResourceException {
+ log.finest("getMaxConnections()");
+ return 0; //TODO
+ }
+
+ @Override
+ public String getUserName() throws ResourceException {
+ log.finest("getUserName()");
+ return null; //TODO
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/resources/META-INF/LICENSE b/chatterbox-slack/chatterbox-slack-impl/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-slack/chatterbox-slack-impl/src/main/resources/META-INF/NOTICE b/chatterbox-slack/chatterbox-slack-impl/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..22c327e
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-impl/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+Slack Connector :: Resource Adapter Implementation
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-slack/chatterbox-slack-rar/pom.xml b/chatterbox-slack/chatterbox-slack-rar/pom.xml
new file mode 100644
index 0000000..03025b5
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-rar/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-slack-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-slack-rar</artifactId>
+ <packaging>rar</packaging>
+ <name>Chatterbox :: Slack :: Resource Adapter</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-slack-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/LICENSE b/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/NOTICE b/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/NOTICE
new file mode 100644
index 0000000..626516d
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/NOTICE
@@ -0,0 +1,5 @@
+Slack Connector :: Resource Adapter
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/ra.xml b/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/ra.xml
new file mode 100644
index 0000000..3d3d7b6
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-rar/src/main/rar/META-INF/ra.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<connector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/connector_1_7.xsd"
+ version="1.7">
+ <description>Chatterbox Slack Connector</description>
+ <display-name>Chatterbox Slack Connector</display-name>
+ <eis-type>Slack Connector</eis-type>
+ <resourceadapter-version>1.0</resourceadapter-version>
+ <license>
+ <license-required>false</license-required>
+ </license>
+ <resourceadapter>
+ <resourceadapter-class>org.apache.tomee.chatterbox.slack.adapter.SlackResourceAdapter</resourceadapter-class>
+ <config-property>
+ <config-property-name>token</config-property-name>
+ <config-property-type>String</config-property-type>
+ </config-property>
+ <outbound-resourceadapter>
+ <connection-definition>
+ <managedconnectionfactory-class>org.apache.tomee.chatterbox.slack.adapter.out.SlackManagedConnectionFactory
+ </managedconnectionfactory-class>
+ <connectionfactory-interface>SlackConnectionFactory
+ </connectionfactory-interface>
+ <connectionfactory-impl-class>org.apache.tomee.chatterbox.slack.adapter.out.SlackConnectionFactoryImpl
+ </connectionfactory-impl-class>
+ <connection-interface>SlackConnection</connection-interface>
+ <connection-impl-class>org.apache.tomee.chatterbox.slack.adapter.out.SlackConnectionImpl</connection-impl-class>
+ </connection-definition>
+ <transaction-support>NoTransaction</transaction-support>
+ <reauthentication-support>false</reauthentication-support>
+ </outbound-resourceadapter>
+ <inbound-resourceadapter>
+ <messageadapter>
+ <messagelistener>
+ <messagelistener-type>InboundListener</messagelistener-type>
+ <activationspec>
+ <activationspec-class>org.apache.tomee.chatterbox.slack.adapter.SlackActivationSpec</activationspec-class>
+ </activationspec>
+ </messagelistener>
+ </messageadapter>
+ </inbound-resourceadapter>
+ </resourceadapter>
+</connector>
diff --git a/chatterbox-slack/chatterbox-slack-sample-war/pom.xml b/chatterbox-slack/chatterbox-slack-sample-war/pom.xml
new file mode 100644
index 0000000..1f94c31
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-sample-war/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-slack-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-slack-sample-war</artifactId>
+ <packaging>war</packaging>
+ <name>Chatterbox :: Slack :: Sample</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-slack-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-slack-impl</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>apache-tomee</artifactId>
+ <version>${version.tomee}</version>
+ <classifier>plus</classifier>
+ <type>zip</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.openejb.maven</groupId>
+ <artifactId>tomee-maven-plugin</artifactId>
+ <version>${version.tomee}</version>
+ <configuration>
+ <tomeeVersion>${version.tomee}</tomeeVersion>
+ <tomeeClassifier>plus</tomeeClassifier>
+ <libs>
+ <lib>org.apache.tomee.chatterbox:chatterbox-slack-api:${project.version}:jar</lib>
+ <lib>org.tomitribe:tomitribe-util:1.1.0:jar</lib>
+ <lib>org.tomitribe:tomitribe-crest-api:0.3:jar</lib>
+ </libs>
+ <apps>
+ <app>org.apache.tomee.chatterbox:chatterbox-slack-rar:${project.version}:rar</app>
+ </apps>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/chatterbox-slack/chatterbox-slack-sample-war/src/main/java/org/superbiz/Sender.java b/chatterbox-slack/chatterbox-slack-sample-war/src/main/java/org/superbiz/Sender.java
new file mode 100644
index 0000000..a89a17a
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-sample-war/src/main/java/org/superbiz/Sender.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz;
+
+import org.apache.tomee.chatterbox.slack.api.SlackConnection;
+import org.apache.tomee.chatterbox.slack.api.SlackConnectionFactory;
+
+import javax.annotation.Resource;
+import javax.ejb.Lock;
+import javax.ejb.LockType;
+import javax.ejb.Singleton;
+import javax.resource.ResourceException;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
+@Singleton
+@Lock(LockType.READ)
+@Path("sender")
+public class Sender {
+
+ @Resource
+ private SlackConnectionFactory cf;
+
+ @Path("{channel}")
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN)
+ public void sendMessage(@PathParam("channel") final String channel, final String message) {
+ try {
+ final SlackConnection connection = cf.getConnection();
+ connection.sendMessage(channel, message);
+ connection.close();
+ } catch (ResourceException e) {
+ // ignore
+ }
+ }
+
+}
diff --git a/chatterbox-slack/chatterbox-slack-sample-war/src/main/java/org/superbiz/SystemBean.java b/chatterbox-slack/chatterbox-slack-sample-war/src/main/java/org/superbiz/SystemBean.java
new file mode 100644
index 0000000..7daf0cc
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-sample-war/src/main/java/org/superbiz/SystemBean.java
@@ -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.
+ */
+package org.superbiz;
+
+import org.apache.tomee.chatterbox.slack.api.InboundListener;
+import org.tomitribe.crest.api.Command;
+import org.tomitribe.util.PrintString;
+
+import javax.ejb.MessageDriven;
+import java.util.Map;
+import java.util.TreeSet;
+
+@MessageDriven(name = "Receiver")
+public class SystemBean implements InboundListener {
+
+ @Command
+ public String date() {
+ return String.format("%tc", System.currentTimeMillis());
+ }
+
+ @Command
+ public String env() {
+ final PrintString out = new PrintString();
+
+ final Map<String, String> env = System.getenv();
+
+ for (String key : new TreeSet<String>(env.keySet())) {
+ out.printf("%s = %s%n", key, env.get(key));
+ }
+
+ return out.toString();
+ }
+
+ @Command
+ public String properties() {
+ final PrintString out = new PrintString();
+
+ System.getProperties().list(out);
+
+ return out.toString();
+ }
+}
diff --git a/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/LICENSE b/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/NOTICE b/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..57a46af
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+Slack Connector :: Sample WAR
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/ejb-jar.xml b/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/ejb-jar.xml
new file mode 100644
index 0000000..09cfc43
--- /dev/null
+++ b/chatterbox-slack/chatterbox-slack-sample-war/src/main/resources/META-INF/ejb-jar.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
+ version="3.1">
+ <display-name>slack-connector-sample-ejb</display-name>
+</ejb-jar>
diff --git a/chatterbox-slack/pom.xml b/chatterbox-slack/pom.xml
new file mode 100644
index 0000000..4c5f4f9
--- /dev/null
+++ b/chatterbox-slack/pom.xml
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-slack-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>0.3-SNAPSHOT</version>
+ <name>Chatterbox :: Slack</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.arquillian>1.1.1.Final</version.arquillian>
+ <version.shrinkwrap.descriptor>2.0.0-alpha-5</version.shrinkwrap.descriptor>
+ <version.shrinkwrap.shrinkwrap>1.0.1</version.shrinkwrap.shrinkwrap>
+ <version.tomee>1.7.2</version.tomee>
+ <version.openejb>4.7.2</version.openejb>
+ <version.crest>0.3</version.crest>
+ <maven.checkstyle.plugin.version>2.16</maven.checkstyle.plugin.version>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>jitpack.io</id>
+ <url>https://jitpack.io</url>
+ </repository>
+ </repositories>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-crest</artifactId>
+ <version>${version.crest}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-crest-api</artifactId>
+ <version>${version.crest}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ <version>1.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-core</artifactId>
+ <version>0.9.0</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <version>7.0</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <modules>
+ <module>chatterbox-slack-api</module>
+ <module>chatterbox-slack-impl</module>
+ <module>chatterbox-slack-rar</module>
+ <module>chatterbox-slack-sample-war</module>
+ </modules>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <pluginManagement>
+ <plugins>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>reserve-network-port</id>
+ <phase>process-test-classes</phase>
+ <goals>
+ <goal>reserve-network-port</goal>
+ </goals>
+ <configuration>
+ <portNames>
+ <portName>tomee.http.port</portName>
+ <portName>tomee.shutdown.port</portName>
+ </portNames>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-test-libs</id>
+ <phase>process-test-resources</phase>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </artifactItem>
+ </artifactItems>
+ <outputDirectory>
+ ${project.build.directory}/test-libs
+ </outputDirectory>
+ <stripVersion>true</stripVersion>
+ </configuration>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <optimize>true</optimize>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>tomee-plus-remote</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <tomee.version>${version.tomee}</tomee.version>
+ <tomee.classifier>plus</tomee.classifier>
+ </properties>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <tomee.classifier>${tomee.classifier}</tomee.classifier>
+ <tomee.version>${tomee.version}</tomee.version>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>arquillian-tomee-remote</artifactId>
+ <version>${tomee.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <version>${version.arquillian}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <version>${version.arquillian}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.shrinkwrap.descriptors</groupId>
+ <artifactId>shrinkwrap-descriptors-impl-javaee</artifactId>
+ <version>${version.shrinkwrap.descriptor}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.shrinkwrap.resolver</groupId>
+ <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
+ <version>2.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>apache-tomee</artifactId>
+ <version>${tomee.version}</version>
+ <classifier>${tomee.classifier}</classifier>
+ <type>zip</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ </profile>
+ </profiles>
+</project>
diff --git a/chatterbox-twitter/chatterbox-twitter-api/pom.xml b/chatterbox-twitter/chatterbox-twitter-api/pom.xml
new file mode 100644
index 0000000..1acf15c
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-twitter-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-twitter-api</artifactId>
+ <packaging>jar</packaging>
+ <name>Chatterbox :: Twitter :: API</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.arquillian>1.1.1.Final</version.arquillian>
+ <version.shrinkwrap.descriptor>2.0.0-alpha-5</version.shrinkwrap.descriptor>
+ <version.shrinkwrap.shrinkwrap>1.0.1</version.shrinkwrap.shrinkwrap>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/InvokeAllMatches.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/InvokeAllMatches.java
new file mode 100644
index 0000000..3eb5344
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/InvokeAllMatches.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+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;
+
+@Inherited
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface InvokeAllMatches {
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/Response.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/Response.java
new file mode 100644
index 0000000..222a051
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/Response.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+public class Response {
+
+ private final boolean prefixReply;
+ private final String message;
+ private final Object dialog;
+
+ public Response(boolean prefixReply, String message, Object dialog) {
+ this.prefixReply = prefixReply;
+ this.message = message;
+ this.dialog = dialog;
+ }
+
+ public static ResponseBuilder prefixReply(final boolean prefixReply) {
+ return new ResponseBuilder().prefixReply(prefixReply);
+ }
+
+ public static ResponseBuilder message(final String message) {
+ return new ResponseBuilder().message(message);
+ }
+
+ public static ResponseBuilder dialog(final Object dialog) {
+ return new ResponseBuilder().dialog(dialog);
+ }
+
+ public boolean isPrefixReply() {
+ return prefixReply;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Object getDialog() {
+ return dialog;
+ }
+
+ public static class ResponseBuilder {
+ private boolean prefixReply;
+ private String message;
+ private Object dialog;
+
+ public ResponseBuilder prefixReply(final boolean prefixReply) {
+ this.prefixReply = prefixReply;
+ return this;
+ }
+
+ public ResponseBuilder message(final String message) {
+ this.message = message;
+ return this;
+ }
+
+ public ResponseBuilder dialog(final Object dialog) {
+ this.dialog = dialog;
+ return this;
+ }
+
+ public Response build() {
+ return new Response(prefixReply, message, dialog);
+ }
+ }
+
+}
+
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/Tweet.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/Tweet.java
new file mode 100644
index 0000000..cc6dd02
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/Tweet.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+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;
+
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Tweet {
+ String value() default "";
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TweetException.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TweetException.java
new file mode 100644
index 0000000..325b36a
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TweetException.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+public class TweetException extends Exception {
+
+ public TweetException() {
+ }
+
+ public TweetException(final Throwable cause) {
+ super(cause);
+ }
+
+ public TweetException(final String message) {
+ super(message);
+ }
+
+ public TweetException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TweetParam.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TweetParam.java
new file mode 100644
index 0000000..39d8165
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TweetParam.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+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;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Target(ElementType.PARAMETER)
+public @interface TweetParam {
+ String value() default "";
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterConnection.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterConnection.java
new file mode 100755
index 0000000..beafb3e
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterConnection.java
@@ -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.
+ */
+
+package org.apache.tomee.chatterbox.twitter.api;
+
+public interface TwitterConnection {
+ public void sendMessage(final String message) throws TweetException;
+
+ public void close();
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterConnectionFactory.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterConnectionFactory.java
new file mode 100755
index 0000000..1f94699
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterConnectionFactory.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+import javax.resource.Referenceable;
+import javax.resource.ResourceException;
+import java.io.Serializable;
+
+public interface TwitterConnectionFactory extends Serializable, Referenceable {
+ public TwitterConnection getConnection() throws ResourceException;
+
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterUpdates.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterUpdates.java
new file mode 100644
index 0000000..d24c425
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/TwitterUpdates.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public interface TwitterUpdates {
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/User.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/User.java
new file mode 100644
index 0000000..1b84d3d
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/User.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+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;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Target(ElementType.METHOD)
+public @interface User {
+
+ String value() default "";
+
+
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/UserParam.java b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/UserParam.java
new file mode 100644
index 0000000..3ac04ae
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/java/org/apache/tomee/chatterbox/twitter/api/UserParam.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.api;
+
+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;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Target(ElementType.PARAMETER)
+public @interface UserParam {
+ String value() default "";
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/resources/META-INF/LICENSE b/chatterbox-twitter/chatterbox-twitter-api/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-twitter/chatterbox-twitter-api/src/main/resources/META-INF/NOTICE b/chatterbox-twitter/chatterbox-twitter-api/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..d60dfbb
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-api/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+Twitter Connector :: API
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/pom.xml b/chatterbox-twitter/chatterbox-twitter-impl/pom.xml
new file mode 100644
index 0000000..a3dbca5
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-twitter-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-twitter-impl</artifactId>
+ <packaging>jar</packaging>
+ <name>Chatterbox :: Twitter :: Resource Adapter Implementation</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-twitter-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>openejb-core</artifactId>
+ <version>${version.openejb}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.twitter</groupId>
+ <artifactId>hbc-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.twitter</groupId>
+ <artifactId>hbc-twitter4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/StatusChangeListener.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/StatusChangeListener.java
new file mode 100644
index 0000000..679c6a9
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/StatusChangeListener.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import twitter4j.Status;
+
+public interface StatusChangeListener {
+ void onStatus(Status status);
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/Template.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/Template.java
new file mode 100644
index 0000000..3eb2f29
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/Template.java
@@ -0,0 +1,387 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Template {
+
+ public static final String LIMITED_REGEX_SUFFIX = "(/.*)?";
+ public static final String FINAL_MATCH_GROUP = "FINAL_MATCH_GROUP";
+ private static final String DEFAULT_PATH_VARIABLE_REGEX = "([^/]+?)";
+ private static final String CHARACTERS_TO_ESCAPE = ".*+$()";
+
+ private final String template;
+ private final List<String> variables = new ArrayList<String>();
+ private final List<String> customVariables = new ArrayList<String>();
+ private final Pattern templateRegexPattern;
+ private final String literals;
+ private final List<UriChunk> uriChunks;
+
+ public Template(final String theTemplate) {
+ template = theTemplate;
+ final StringBuilder literalChars = new StringBuilder();
+ final StringBuilder patternBuilder = new StringBuilder();
+ final CurlyBraceTokenizer tok = new CurlyBraceTokenizer(template);
+ uriChunks = new ArrayList<>();
+ while (tok.hasNext()) {
+ final String templatePart = tok.next();
+ final UriChunk chunk = UriChunk.createUriChunk(templatePart);
+ uriChunks.add(chunk);
+ if (chunk instanceof Literal) {
+ final String substr = escapeCharacters(chunk.getValue());
+ literalChars.append(substr);
+ patternBuilder.append(substr);
+ } else if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ variables.add(var.getName());
+ if (var.getPattern() != null) {
+ customVariables.add(var.getName());
+ patternBuilder.append('(');
+ patternBuilder.append(var.getPattern());
+ patternBuilder.append(')');
+ } else {
+ patternBuilder.append(DEFAULT_PATH_VARIABLE_REGEX);
+ }
+ }
+ }
+ literals = literalChars.toString();
+
+ final int endPos = patternBuilder.length() - 1;
+ final boolean endsWithSlash = (endPos >= 0) && patternBuilder.charAt(endPos) == '/';
+ if (endsWithSlash) {
+ patternBuilder.deleteCharAt(endPos);
+ }
+ patternBuilder.append(LIMITED_REGEX_SUFFIX);
+
+ templateRegexPattern = Pattern.compile(patternBuilder.toString());
+ }
+
+ private static String escapeCharacters(final String expression) {
+ final StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < expression.length(); i++) {
+ final char ch = expression.charAt(i);
+ sb.append(isReservedCharacter(ch) ? "\\" + ch : ch);
+ }
+ return sb.toString();
+ }
+
+ private static boolean isReservedCharacter(final char ch) {
+ return CHARACTERS_TO_ESCAPE.indexOf(ch) != -1;
+ }
+
+ public String getLiteralChars() {
+ return literals;
+ }
+
+ public String getValue() {
+ return template;
+ }
+
+ public String getPatternValue() {
+ return templateRegexPattern.toString();
+ }
+
+ public List<String> getVariables() {
+ return Collections.unmodifiableList(variables);
+ }
+
+ public List<String> getCustomVariables() {
+ return Collections.unmodifiableList(customVariables);
+ }
+
+ public boolean match(final String uri, final Map<String, List<String>> templateVariableToValue) {
+
+ if (uri == null) {
+ return (templateRegexPattern == null);
+ }
+
+ if (templateRegexPattern == null) {
+ return false;
+ }
+
+ Matcher m = templateRegexPattern.matcher(uri);
+ if (!m.matches()) {
+ return false;
+ }
+
+ // Assign the matched template values to template variables
+ final int groupCount = m.groupCount();
+
+ int i = 1;
+ for (final String name : variables) {
+ while (i <= groupCount) {
+ final String value = m.group(i++);
+ if ((value == null || value.length() == 0 && i < groupCount)
+ && variables.size() + 1 < groupCount) {
+ continue;
+ }
+
+ if (templateVariableToValue.get(name) == null) {
+ templateVariableToValue.put(name, new ArrayList<>());
+ }
+
+ templateVariableToValue.get(name).add(value);
+ break;
+ }
+ }
+ // The right hand side value, might be used to further resolve
+ // sub-resources.
+
+ String finalGroup = m.group(groupCount);
+ if (finalGroup == null) {
+ finalGroup = "";
+ }
+
+ templateVariableToValue.put(FINAL_MATCH_GROUP, Collections.singletonList(finalGroup));
+ return true;
+ }
+
+ public String substitute(final List<String> values) throws IllegalArgumentException {
+ if (values == null) {
+ throw new IllegalArgumentException("values is null");
+ }
+ final Iterator<String> iter = values.iterator();
+ final StringBuilder sb = new StringBuilder();
+ for (final UriChunk chunk : uriChunks) {
+ if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ if (iter.hasNext()) {
+ final String value = iter.next();
+ if (!var.matches(value)) {
+ throw new IllegalArgumentException("Value '" + value + "' does not match variable "
+ + var.getName() + " with value "
+ + var.getPattern());
+ }
+ sb.append(value);
+ } else {
+ sb.append(var);
+ }
+ } else {
+ sb.append(chunk);
+ }
+ }
+ return sb.toString();
+ }
+
+ String substitute(final Map<String, ?> valuesMap) throws IllegalArgumentException {
+ return this.substitute(valuesMap, Collections.<String>emptySet(), false);
+ }
+
+ public String substitute(final Map<String, ?> valuesMap,
+ final Set<String> encodePathSlashVars,
+ final boolean allowUnresolved) throws IllegalArgumentException {
+ if (valuesMap == null) {
+ throw new IllegalArgumentException("valuesMap is null");
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (final UriChunk chunk : uriChunks) {
+ if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ final Object value = valuesMap.get(var.getName());
+ if (value != null) {
+ String sval = value.toString();
+ if (!var.matches(sval)) {
+ throw new IllegalArgumentException("Value '" + sval + "' does not match variable "
+ + var.getName() + " with value "
+ + var.getPattern());
+ }
+ if (encodePathSlashVars.contains(var.getName())) {
+ sval = sval.replaceAll("/", "%2F");
+ }
+ sb.append(sval);
+ } else if (allowUnresolved) {
+ sb.append(chunk);
+ } else {
+ throw new IllegalArgumentException("Template variable " + var.getName()
+ + " has no matching value");
+ }
+ } else {
+ sb.append(chunk);
+ }
+ }
+ return sb.toString();
+ }
+
+ private abstract static class UriChunk {
+ public static UriChunk createUriChunk(final String uriChunk) {
+ if (uriChunk == null || "".equals(uriChunk)) {
+ throw new IllegalArgumentException("uriChunk is empty");
+ }
+ UriChunk uriChunkRepresentation = Variable.create(uriChunk);
+ if (uriChunkRepresentation == null) {
+ uriChunkRepresentation = Literal.create(uriChunk);
+ }
+ return uriChunkRepresentation;
+ }
+
+ public abstract String getValue();
+
+ @Override
+ public String toString() {
+ return getValue();
+ }
+ }
+
+ private static final class Literal extends UriChunk {
+ private String value;
+
+ private Literal() {
+ // empty constructor
+ }
+
+ public static Literal create(final String uriChunk) {
+ if (uriChunk == null || "".equals(uriChunk)) {
+ throw new IllegalArgumentException("uriChunk is empty");
+ }
+ final Literal literal = new Literal();
+ literal.value = uriChunk;
+ return literal;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ }
+
+ private static final class Variable extends UriChunk {
+ private static final Pattern VARIABLE_PATTERN = Pattern.compile("(\\w[-\\w\\.]*[ ]*)(\\:(.+))?");
+ private String name;
+ private Pattern pattern;
+
+ private Variable() {
+ // empty constructor
+ }
+
+ public static Variable create(String uriChunk) {
+ final Variable newVariable = new Variable();
+ if (uriChunk == null || "".equals(uriChunk)) {
+ return null;
+ }
+ if (CurlyBraceTokenizer.insideBraces(uriChunk)) {
+ uriChunk = CurlyBraceTokenizer.stripBraces(uriChunk).trim();
+ final Matcher matcher = VARIABLE_PATTERN.matcher(uriChunk);
+ if (matcher.matches()) {
+ newVariable.name = matcher.group(1).trim();
+ if (matcher.group(2) != null && matcher.group(3) != null) {
+ final String patternExpression = matcher.group(3).trim();
+ newVariable.pattern = Pattern.compile(patternExpression);
+ }
+ return newVariable;
+ }
+ }
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPattern() {
+ return pattern != null ? pattern.pattern() : null;
+ }
+
+ public boolean matches(final String value) {
+ if (pattern == null) {
+ return true;
+ } else {
+ return pattern.matcher(value).matches();
+ }
+ }
+
+ @Override
+ public String getValue() {
+ if (pattern != null) {
+ return "{" + name + ":" + pattern + "}";
+ } else {
+ return "{" + name + "}";
+ }
+ }
+ }
+
+ static class CurlyBraceTokenizer {
+
+ private final List<String> tokens = new ArrayList<String>();
+ private int tokenIdx;
+
+ CurlyBraceTokenizer(final String string) {
+ boolean outside = true;
+ int level = 0;
+ int lastIdx = 0;
+ int idx;
+ for (idx = 0; idx < string.length(); idx++) {
+ if (string.charAt(idx) == '{') {
+ if (outside) {
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx));
+ }
+ lastIdx = idx;
+ outside = false;
+ } else {
+ level++;
+ }
+ } else if (string.charAt(idx) == '}' && !outside) {
+ if (level > 0) {
+ level--;
+ } else {
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx + 1));
+ }
+ lastIdx = idx + 1;
+ outside = true;
+ }
+ }
+ }
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx));
+ }
+ }
+
+ public static boolean insideBraces(final String token) {
+ return token.charAt(0) == '{' && token.charAt(token.length() - 1) == '}';
+ }
+
+ public static String stripBraces(final String token) {
+ if (insideBraces(token)) {
+ return token.substring(1, token.length() - 1);
+ } else {
+ return token;
+ }
+ }
+
+ public boolean hasNext() {
+ return tokens.size() > tokenIdx;
+ }
+
+ public String next() {
+ if (hasNext()) {
+ return tokens.get(tokenIdx++);
+ } else {
+ throw new IllegalStateException("no more elements");
+ }
+ }
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterActivationSpec.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterActivationSpec.java
new file mode 100644
index 0000000..f6c3363
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterActivationSpec.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import org.apache.tomee.chatterbox.twitter.api.TwitterUpdates;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.Activation;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.InvalidPropertyException;
+import javax.resource.spi.ResourceAdapter;
+
+@Activation(messageListeners = TwitterUpdates.class)
+public class TwitterActivationSpec implements ActivationSpec {
+
+ private ResourceAdapter resourceAdapter;
+ private Class beanClass;
+
+ public Class getBeanClass() {
+ return beanClass;
+ }
+
+ public void setBeanClass(final Class beanClass) {
+ this.beanClass = beanClass;
+ }
+
+ @Override
+ public void validate() throws InvalidPropertyException {
+ }
+
+ @Override
+ public ResourceAdapter getResourceAdapter() {
+ return resourceAdapter;
+ }
+
+ @Override
+ public void setResourceAdapter(final ResourceAdapter ra) throws ResourceException {
+ this.resourceAdapter = ra;
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterConnectionFactoryImpl.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterConnectionFactoryImpl.java
new file mode 100755
index 0000000..a71839b
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterConnectionFactoryImpl.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import org.apache.tomee.chatterbox.twitter.api.TwitterConnection;
+import org.apache.tomee.chatterbox.twitter.api.TwitterConnectionFactory;
+
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import java.util.logging.Logger;
+
+public class TwitterConnectionFactoryImpl implements TwitterConnectionFactory {
+ private static final long serialVersionUID = 1L;
+
+ private static Logger log = Logger.getLogger(TwitterConnectionFactoryImpl.class.getName());
+
+ private Reference reference;
+
+ private TwitterManagedConnectionFactory mcf;
+
+ private ConnectionManager connectionManager;
+
+ public TwitterConnectionFactoryImpl() {
+
+ }
+
+ public TwitterConnectionFactoryImpl(TwitterManagedConnectionFactory mcf, ConnectionManager cxManager) {
+ this.mcf = mcf;
+ this.connectionManager = cxManager;
+ }
+
+ @Override
+ public TwitterConnection getConnection() throws ResourceException {
+ log.finest("getConnection()");
+ return (TwitterConnection) connectionManager.allocateConnection(mcf, null);
+ }
+
+ @Override
+ public Reference getReference() throws NamingException {
+ log.finest("getReference()");
+ return reference;
+ }
+
+ @Override
+ public void setReference(Reference reference) {
+ log.finest("setReference()");
+ this.reference = reference;
+ }
+
+
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterConnectionImpl.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterConnectionImpl.java
new file mode 100755
index 0000000..49f58af
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterConnectionImpl.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import org.apache.tomee.chatterbox.twitter.api.TweetException;
+import org.apache.tomee.chatterbox.twitter.api.TwitterConnection;
+import twitter4j.TwitterException;
+
+import java.util.logging.Logger;
+
+public class TwitterConnectionImpl implements TwitterConnection {
+ private static Logger log = Logger.getLogger(TwitterConnectionImpl.class.getName());
+
+ private TwitterManagedConnection mc;
+
+ private TwitterManagedConnectionFactory mcf;
+
+ public TwitterConnectionImpl(TwitterManagedConnection mc, TwitterManagedConnectionFactory mcf) {
+ this.mc = mc;
+ this.mcf = mcf;
+ }
+
+ public void sendMessage(final String message) throws TweetException {
+ try {
+ mc.sendMessage(message);
+ } catch (TwitterException e) {
+ throw new TweetException(e);
+ }
+ }
+
+ public void close() {
+ mc.closeHandle(this);
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnection.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnection.java
new file mode 100755
index 0000000..3cdb9d9
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnection.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import org.apache.tomee.chatterbox.twitter.api.TwitterConnection;
+import twitter4j.TwitterException;
+
+import javax.resource.NotSupportedException;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionEvent;
+import javax.resource.spi.ConnectionEventListener;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.LocalTransaction;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionMetaData;
+import javax.security.auth.Subject;
+import javax.transaction.xa.XAResource;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class TwitterManagedConnection implements ManagedConnection {
+
+ private static Logger log = Logger.getLogger(TwitterManagedConnection.class.getName());
+
+ private PrintWriter logwriter;
+
+ private TwitterManagedConnectionFactory mcf;
+
+ private List<ConnectionEventListener> listeners;
+
+ private TwitterConnectionImpl connection;
+
+ public TwitterManagedConnection(TwitterManagedConnectionFactory mcf) {
+ this.mcf = mcf;
+ this.logwriter = null;
+ this.listeners = Collections.synchronizedList(new ArrayList<ConnectionEventListener>(1));
+ this.connection = null;
+ }
+
+ public Object getConnection(Subject subject,
+ ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("getConnection()");
+ connection = new TwitterConnectionImpl(this, mcf);
+ return connection;
+ }
+
+ public void associateConnection(Object connection) throws ResourceException {
+ log.finest("associateConnection()");
+
+ if (connection == null)
+ throw new ResourceException("Null connection handle");
+
+ if (!(connection instanceof TwitterConnectionImpl))
+ throw new ResourceException("Wrong connection handle");
+
+ this.connection = (TwitterConnectionImpl) connection;
+ }
+
+ public void cleanup() throws ResourceException {
+ log.finest("cleanup()");
+ }
+
+ public void destroy() throws ResourceException {
+ log.finest("destroy()");
+ }
+
+ public void addConnectionEventListener(ConnectionEventListener listener) {
+ log.finest("addConnectionEventListener()");
+
+ if (listener == null) {
+ throw new IllegalArgumentException("Listener is null");
+ }
+
+ listeners.add(listener);
+ }
+
+ public void removeConnectionEventListener(ConnectionEventListener listener) {
+ log.finest("removeConnectionEventListener()");
+ if (listener == null)
+ throw new IllegalArgumentException("Listener is null");
+ listeners.remove(listener);
+ }
+
+ void closeHandle(TwitterConnection handle) {
+ ConnectionEvent event = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
+ event.setConnectionHandle(handle);
+ for (ConnectionEventListener cel : listeners) {
+ cel.connectionClosed(event);
+ }
+ }
+
+ public PrintWriter getLogWriter() throws ResourceException {
+ log.finest("getLogWriter()");
+ return logwriter;
+ }
+
+ public void setLogWriter(PrintWriter out) throws ResourceException {
+ log.finest("setLogWriter()");
+ logwriter = out;
+ }
+
+ public LocalTransaction getLocalTransaction() throws ResourceException {
+ throw new NotSupportedException("getLocalTransaction() not supported");
+ }
+
+ public XAResource getXAResource() throws ResourceException {
+ throw new NotSupportedException("getXAResource() not supported");
+ }
+
+ public ManagedConnectionMetaData getMetaData() throws ResourceException {
+ log.finest("getMetaData()");
+ return new TwitterManagedConnectionMetaData();
+ }
+
+ void sendMessage(final String message) throws TwitterException {
+ log.finest("sendMessage()");
+
+ final TwitterResourceAdapter resourceAdapter = (TwitterResourceAdapter) mcf.getResourceAdapter();
+ resourceAdapter.tweet(message);
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnectionFactory.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnectionFactory.java
new file mode 100755
index 0000000..cdf3827
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnectionFactory.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import org.apache.tomee.chatterbox.twitter.api.TwitterConnection;
+import org.apache.tomee.chatterbox.twitter.api.TwitterConnectionFactory;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionDefinition;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterAssociation;
+import javax.security.auth.Subject;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Logger;
+
+@ConnectionDefinition(connectionFactory = TwitterConnectionFactory.class,
+ connectionFactoryImpl = TwitterConnectionFactoryImpl.class,
+ connection = TwitterConnection.class,
+ connectionImpl = TwitterConnectionImpl.class)
+public class TwitterManagedConnectionFactory implements ManagedConnectionFactory, ResourceAdapterAssociation {
+
+ private static final long serialVersionUID = 1L;
+
+ private static Logger log = Logger.getLogger(TwitterManagedConnectionFactory.class.getName());
+
+ private ResourceAdapter ra;
+
+ private PrintWriter logwriter;
+
+ public TwitterManagedConnectionFactory() {
+
+ }
+
+ public Object createConnectionFactory(ConnectionManager cxManager) throws ResourceException {
+ log.finest("createConnectionFactory()");
+ return new TwitterConnectionFactoryImpl(this, cxManager);
+ }
+
+ public Object createConnectionFactory() throws ResourceException {
+ throw new ResourceException("This resource adapter doesn't support non-managed environments");
+ }
+
+ public ManagedConnection createManagedConnection(Subject subject,
+ ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("createManagedConnection()");
+ return new TwitterManagedConnection(this);
+ }
+
+ public ManagedConnection matchManagedConnections(Set connectionSet,
+ Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("matchManagedConnections()");
+ ManagedConnection result = null;
+ Iterator it = connectionSet.iterator();
+ while (result == null && it.hasNext()) {
+ ManagedConnection mc = (ManagedConnection) it.next();
+ if (mc instanceof TwitterManagedConnection) {
+ result = mc;
+ }
+
+ }
+ return result;
+ }
+
+ public PrintWriter getLogWriter() throws ResourceException {
+ log.finest("getLogWriter()");
+ return logwriter;
+ }
+
+ public void setLogWriter(PrintWriter out) throws ResourceException {
+ log.finest("setLogWriter()");
+ logwriter = out;
+ }
+
+ public ResourceAdapter getResourceAdapter() {
+ log.finest("getResourceAdapter()");
+ return ra;
+ }
+
+ public void setResourceAdapter(ResourceAdapter ra) {
+ log.finest("setResourceAdapter()");
+ this.ra = ra;
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnectionMetaData.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnectionMetaData.java
new file mode 100755
index 0000000..702147b
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterManagedConnectionMetaData.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnectionMetaData;
+import java.util.logging.Logger;
+
+public class TwitterManagedConnectionMetaData implements ManagedConnectionMetaData {
+
+ private static Logger log = Logger.getLogger(TwitterManagedConnectionMetaData.class.getName());
+
+ public TwitterManagedConnectionMetaData() {
+
+ }
+
+ @Override
+ public String getEISProductName() throws ResourceException {
+ log.finest("getEISProductName()");
+ return null; //TODO
+ }
+
+ @Override
+ public String getEISProductVersion() throws ResourceException {
+ log.finest("getEISProductVersion()");
+ return null; //TODO
+ }
+
+ @Override
+ public int getMaxConnections() throws ResourceException {
+ log.finest("getMaxConnections()");
+ return 0; //TODO
+ }
+
+ @Override
+ public String getUserName() throws ResourceException {
+ log.finest("getUserName()");
+ return null; //TODO
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterResourceAdapter.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterResourceAdapter.java
new file mode 100644
index 0000000..091af72
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterResourceAdapter.java
@@ -0,0 +1,443 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import com.twitter.hbc.httpclient.ControlStreamException;
+import org.apache.tomee.chatterbox.twitter.api.InvokeAllMatches;
+import org.apache.tomee.chatterbox.twitter.api.Response;
+import org.apache.tomee.chatterbox.twitter.api.Tweet;
+import org.apache.tomee.chatterbox.twitter.api.TweetParam;
+import org.apache.tomee.chatterbox.twitter.api.User;
+import org.apache.tomee.chatterbox.twitter.api.UserParam;
+import org.tomitribe.util.editor.Converter;
+import twitter4j.Status;
+import twitter4j.StatusUpdate;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.TwitterFactory;
+import twitter4j.auth.AccessToken;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.BootstrapContext;
+import javax.resource.spi.ConfigProperty;
+import javax.resource.spi.Connector;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterInternalException;
+import javax.resource.spi.endpoint.MessageEndpoint;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.transaction.xa.XAResource;
+import javax.validation.constraints.NotNull;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+@Connector(description = "Twitter Resource Adapter", displayName = "Twitter Resource Adapter", eisType = "Twitter Resource Adapter", version = "1.0")
+public class TwitterResourceAdapter implements ResourceAdapter, StatusChangeListener {
+
+ private static final Logger LOGGER = Logger.getLogger(TwitterResourceAdapter.class.getName());
+ private static final Map<String, Response> RESPONSE_MAP = new ConcurrentHashMap<>();
+ final Map<TwitterActivationSpec, EndpointTarget> targets = new ConcurrentHashMap<TwitterActivationSpec, EndpointTarget>();
+ private TwitterStreamingClient client;
+ @ConfigProperty
+ @NotNull
+ private String consumerKey;
+ @ConfigProperty
+ @NotNull
+ private String consumerSecret;
+ @ConfigProperty
+ @NotNull
+ private String accessToken;
+ @ConfigProperty
+ @NotNull
+ private String accessTokenSecret;
+ private Twitter twitter;
+
+ private static List<Method> findMatchingMethods(final Class<?> clazz, final Status status) {
+ return Arrays.asList(clazz.getDeclaredMethods())
+ .stream()
+ .sorted((m1, m2) -> m1.toString().compareTo(m2.toString()))
+ .filter(TwitterResourceAdapter::isPublic)
+ .filter(TwitterResourceAdapter::isNotFinal)
+ .filter(TwitterResourceAdapter::isNotAbstract)
+ .filter(m -> filterTweet(status, m))
+ .filter(m -> filterUser(status, m))
+ .filter(m -> filterGetMethod(status, m))
+ .collect(Collectors.toList());
+ }
+
+ private static boolean filterUser(final Status status, final Method m) {
+ return !m.isAnnotationPresent(User.class) || "".equals(m.getAnnotation(User.class).value())
+ || templateMatches(m.getAnnotation(User.class).value(), status.getUser().getScreenName());
+ }
+
+ private static boolean filterTweet(final Status status, final Method m) {
+ return !m.isAnnotationPresent(Tweet.class) || "".equals(m.getAnnotation(Tweet.class).value())
+ || templateMatches(m.getAnnotation(Tweet.class).value(), getNormalizedText(status));
+ }
+
+ private static String getNormalizedText(Status status) {
+ String text = status.getText();
+ while (text.startsWith("@")) {
+ text = text.replaceFirst("@?(\\w){1,15}(\\s+)", "");
+ }
+ return text;
+ }
+
+ private static boolean filterGetMethod(final Status status, final Method m) {
+ return !(Response.class.isAssignableFrom(m.getDeclaringClass())
+ && "getMessage".equals(m.getName())
+ && m.getParameterCount() == 0);
+ }
+
+ private static boolean templateMatches(final String pattern, final String input) {
+ try {
+ if (Pattern.matches(pattern, input)) {
+ return true;
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+
+ final Template template = new Template(pattern);
+ final Map<String, List<String>> values = new HashMap<>();
+ return template.match(input, values);
+ }
+
+ private static boolean isPublic(final Method m) {
+ return Modifier.isPublic(m.getModifiers());
+ }
+
+ private static boolean isNotAbstract(final Method m) {
+ return !Modifier.isAbstract(m.getModifiers());
+ }
+
+ private static boolean isNotFinal(final Method m) {
+ return !Modifier.isFinal(m.getModifiers());
+ }
+
+ public static Object[] getValues(final Method method, final Status status) {
+
+ if (method == null) {
+ return null;
+ }
+
+ final Parameter[] parameters = method.getParameters();
+ if (parameters.length == 0) {
+ return new Object[0];
+ }
+
+ final Template tweetTemplate = getTemplate(method.getAnnotation(Tweet.class));
+ final Map<String, List<String>> tweetParamValues = new HashMap<>();
+ if (tweetTemplate != null) {
+ tweetTemplate.match(getNormalizedText(status), tweetParamValues);
+ }
+
+ final Template userTemplate = getTemplate(method.getAnnotation(User.class));
+ final Map<String, List<String>> userParamValues = new HashMap<>();
+ if (userTemplate != null) {
+ userTemplate.match(status.getUser().getScreenName(), userParamValues);
+ }
+
+ final Object[] values = new Object[parameters.length];
+
+ for (int i = 0; i < parameters.length; i++) {
+ final Parameter parameter = parameters[i];
+
+ values[i] = null;
+
+ if (parameter.isAnnotationPresent(TweetParam.class)) {
+ final TweetParam tweetParam = parameter.getAnnotation(TweetParam.class);
+ if (tweetParam.value() == null || tweetParam.value().length() == 0) {
+ values[i] = Converter.convert(getNormalizedText(status), parameter.getType(), null);
+ } else {
+ final List<String> paramValues = tweetParamValues.get(tweetParam.value());
+ final String paramValue = paramValues == null || paramValues.size() == 0 ? null : paramValues.get(0);
+ values[i] = Converter.convert(paramValue, parameter.getType(), null);
+ }
+ }
+
+ if (parameter.isAnnotationPresent(UserParam.class)) {
+ final UserParam userParam = parameter.getAnnotation(UserParam.class);
+ if (userParam.value() == null || userParam.value().length() == 0) {
+ values[i] = Converter.convert(status.getUser().getScreenName(), parameter.getType(), null);
+ } else {
+ final List<String> paramValues = userParamValues.get(userParam.value());
+ final String paramValue = paramValues == null || paramValues.size() == 0 ? null : paramValues.get(0);
+ values[i] = Converter.convert(paramValue, parameter.getType(), null);
+ }
+ }
+ }
+
+ return values;
+ }
+
+ private static Template getTemplate(final Annotation annotation) {
+ if (annotation == null) {
+ return null;
+ }
+
+ try {
+
+ final Method patternMethod = annotation.getClass().getMethod("value");
+ if (patternMethod == null) {
+ return null;
+ }
+
+ if (!String.class.equals(patternMethod.getReturnType())) {
+ return null;
+ }
+
+ final String pattern = (String) patternMethod.invoke(annotation);
+ return new Template(pattern);
+ } catch (final Exception e) {
+ // ignore
+ }
+
+ return null;
+ }
+
+ public void start(final BootstrapContext bootstrapContext) throws ResourceAdapterInternalException {
+
+ LOGGER.info("Starting " + this);
+
+ client = new TwitterStreamingClient(this, consumerKey, consumerSecret, accessToken, accessTokenSecret);
+ twitter = new TwitterFactory().getInstance();
+ twitter.setOAuthConsumer(consumerKey, consumerSecret);
+ twitter.setOAuthAccessToken(new AccessToken(accessToken, accessTokenSecret));
+
+
+ try {
+ client.run();
+ } catch (InterruptedException | ControlStreamException | IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void stop() {
+ LOGGER.info("Stopping " + this);
+ client.stop();
+ }
+
+ public void endpointActivation(final MessageEndpointFactory messageEndpointFactory, final ActivationSpec activationSpec)
+ throws ResourceException {
+ final TwitterActivationSpec twitterActivationSpec = (TwitterActivationSpec) activationSpec;
+ final MessageEndpoint messageEndpoint = messageEndpointFactory.createEndpoint(null);
+
+ final Class<?> endpointClass = twitterActivationSpec.getBeanClass() != null ? twitterActivationSpec
+ .getBeanClass() : messageEndpointFactory.getEndpointClass();
+
+ LOGGER.info("Deploying " + endpointClass.getName());
+
+ final EndpointTarget target = new EndpointTarget(messageEndpoint, endpointClass);
+ targets.put(twitterActivationSpec, target);
+
+ }
+
+ public void endpointDeactivation(final MessageEndpointFactory messageEndpointFactory, final ActivationSpec activationSpec) {
+ final TwitterActivationSpec twitterActivationSpec = (TwitterActivationSpec) activationSpec;
+
+ final EndpointTarget endpointTarget = targets.get(twitterActivationSpec);
+ if (endpointTarget == null) {
+ throw new IllegalStateException("No EndpointTarget to undeploy for ActivationSpec " + activationSpec);
+ }
+
+ endpointTarget.messageEndpoint.release();
+ }
+
+ public XAResource[] getXAResources(final ActivationSpec[] activationSpecs) throws ResourceException {
+ return new XAResource[0];
+ }
+
+ @Override
+ public void onStatus(final Status status) {
+
+ final String username = status.getUser().getScreenName();
+ final Response response = RESPONSE_MAP.remove(username);
+
+ if (response != null && response.getDialog() != null) {
+ // pull the response object from the map
+
+ final Object dialog = response.getDialog();
+
+ try {
+ final List<Method> matchingMethods = findMatchingMethods(dialog.getClass(), status);
+
+ if (dialog.getClass().isAnnotationPresent(InvokeAllMatches.class)) {
+ for (final Method method : matchingMethods) {
+ LOGGER.log(Level.INFO, "Invoking method " + method.toString() + " for " + getNormalizedText(status));
+ final Object[] values = getValues(method, status);
+ final Object result = method.invoke(dialog, values);
+ processResponse(status, result);
+ }
+ } else {
+ final Method method = matchingMethods.get(0);
+ LOGGER.log(Level.INFO, "Invoking method " + method.toString() + " for " + getNormalizedText(status));
+ final Object[] values = getValues(method, status);
+ final Object result = method.invoke(dialog, values);
+ processResponse(status, result);
+ }
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ LOGGER.severe("Unable to call response object:" + e.getMessage());
+ RESPONSE_MAP.remove(status.getUser().getScreenName());
+ }
+ } else {
+ for (final EndpointTarget endpointTarget : this.targets.values()) {
+ endpointTarget.invoke(status);
+ }
+ }
+ }
+
+ private void processResponse(final Status status, final Object result) {
+ if (Response.class.isInstance(result)) {
+ final Response response = Response.class.cast(result);
+ RESPONSE_MAP.put(status.getUser().getScreenName(), response);
+ try {
+ replyTo(status, response.getMessage());
+ } catch (TwitterException e) {
+ LOGGER.severe("Unable to send tweet" + e.getMessage());
+ }
+ } else {
+ RESPONSE_MAP.remove(status.getUser().getScreenName());
+ }
+
+ if (String.class.isInstance(result)) {
+ RESPONSE_MAP.remove(status.getUser().getScreenName());
+ try {
+ replyTo(status, String.class.cast(result));
+ } catch (TwitterException e) {
+ LOGGER.severe("Unable to send tweet" + e.getMessage());
+ }
+ }
+ }
+
+ private void replyTo(final Status status, final String reply) throws TwitterException {
+ replyTo(status, reply, true);
+ }
+
+ private void replyTo(final Status status, final String reply, final boolean prefix) throws TwitterException {
+ final String message;
+
+ if (prefix) {
+ message = "@" + status.getUser().getScreenName() + " " + reply;
+ } else {
+ message = reply;
+ }
+
+ final StatusUpdate statusUpdate = new StatusUpdate(message);
+ statusUpdate.setInReplyToStatusId(status.getId());
+ twitter.updateStatus(statusUpdate);
+ }
+
+ public void tweet(final String tweet) throws TwitterException {
+ twitter.updateStatus(tweet);
+ }
+
+ @Override
+ public String toString() {
+ return "TwitterResourceAdapter{" +
+ "consumerKey='" + consumerKey + '\'' +
+ ", consumerSecret='" + consumerSecret + '\'' +
+ ", accessToken='" + accessToken + '\'' +
+ ", accessTokenSecret='" + accessTokenSecret + '\'' +
+ '}';
+ }
+
+ public static class TweetWrapper {
+ private final String user;
+ private final String text;
+ // private final String
+
+
+ public TweetWrapper(final Status status) {
+ user = status.getUser().getScreenName();
+ text = status.getText();
+ }
+
+ @Override
+ public String toString() {
+ return "Tweet{" +
+ "user='" + user + '\'' +
+ ", text='" + text + '\'' +
+ '}';
+ }
+ }
+
+ public class EndpointTarget {
+ private final MessageEndpoint messageEndpoint;
+ private final Class<?> clazz;
+
+ public EndpointTarget(final MessageEndpoint messageEndpoint, final Class<?> clazz) {
+ this.messageEndpoint = messageEndpoint;
+ this.clazz = clazz;
+ }
+
+ public void invoke(final Status status) {
+
+ // wrapper object for logging purposes
+ final TweetWrapper tweet = new TweetWrapper(status);
+
+ // find matching method(s)
+
+ final List<Method> matchingMethods = findMatchingMethods(clazz, status);
+
+ if (matchingMethods == null || matchingMethods.size() == 0) {
+ // log this
+ LOGGER.log(Level.INFO, "No method to match " + tweet);
+ return;
+ }
+
+ if (this.clazz.isAnnotationPresent(InvokeAllMatches.class)) {
+ for (final Method method : matchingMethods) {
+ LOGGER.log(Level.INFO, "Invoking method " + method.toString() + " for " + tweet);
+ invoke(method, status);
+ }
+ } else {
+ final Method method = matchingMethods.get(0);
+ LOGGER.log(Level.INFO, "Invoking method " + method.toString() + " for " + tweet);
+ invoke(method, status);
+ }
+ }
+
+ private void invoke(final Method method, final Status status) {
+ try {
+ try {
+ messageEndpoint.beforeDelivery(method);
+ final Object[] values = getValues(method, status);
+ final Object result = method.invoke(messageEndpoint, values);
+ processResponse(status, result);
+ } finally {
+ messageEndpoint.afterDelivery();
+ }
+ } catch (final NoSuchMethodException | ResourceException | IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterStreamingClient.java b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterStreamingClient.java
new file mode 100644
index 0000000..f5fb7b1
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterStreamingClient.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import com.google.common.collect.Lists;
+import com.twitter.hbc.ClientBuilder;
+import com.twitter.hbc.core.Constants;
+import com.twitter.hbc.core.endpoint.UserstreamEndpoint;
+import com.twitter.hbc.core.processor.StringDelimitedProcessor;
+import com.twitter.hbc.httpclient.BasicClient;
+import com.twitter.hbc.httpclient.ControlStreamException;
+import com.twitter.hbc.httpclient.auth.Authentication;
+import com.twitter.hbc.httpclient.auth.OAuth1;
+import com.twitter.hbc.twitter4j.Twitter4jUserstreamClient;
+import twitter4j.Status;
+import twitter4j.UserStreamAdapter;
+
+import java.io.IOException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class TwitterStreamingClient {
+
+ private final StatusChangeListener statusChangeListener;
+ private final String consumerKey;
+ private final String consumerSecret;
+ private final String accessToken;
+ private final String accessTokenSecret;
+ private final UserStreamAdapter listener = new UserStreamAdapter() {
+ @Override
+ public void onStatus(final Status status) {
+ statusChangeListener.onStatus(status);
+ }
+ };
+ private Twitter4jUserstreamClient t4jClient;
+
+ public TwitterStreamingClient(
+ final StatusChangeListener statusChangeListener,
+ final String consumerKey,
+ final String consumerSecret,
+ final String accessToken,
+ final String accessTokenSecret) {
+
+ this.statusChangeListener = statusChangeListener;
+ this.consumerKey = consumerKey;
+ this.consumerSecret = consumerSecret;
+ this.accessToken = accessToken;
+ this.accessTokenSecret = accessTokenSecret;
+ }
+
+ public void run() throws InterruptedException, ControlStreamException, IOException {
+ // Create an appropriately sized blocking queue
+ final BlockingQueue<String> queue = new LinkedBlockingQueue<String>(10000);
+
+ final UserstreamEndpoint endpoint = new UserstreamEndpoint();
+ final Authentication auth = new OAuth1(consumerKey, consumerSecret, accessToken, accessTokenSecret);
+
+ // Create a new BasicClient. By default gzip is enabled.
+ final BasicClient client = new ClientBuilder()
+ .hosts(Constants.SITESTREAM_HOST)
+ .endpoint(endpoint)
+ .authentication(auth)
+ .processor(new StringDelimitedProcessor(queue))
+ .build();
+
+ // Create an executor service which will spawn threads to do the actual work of parsing the incoming messages and
+ // calling the listeners on each message
+ final int numProcessingThreads = 4;
+ final ExecutorService service = Executors.newFixedThreadPool(numProcessingThreads);
+
+ // Wrap our BasicClient with the twitter4j client
+ t4jClient = new Twitter4jUserstreamClient(
+ client, queue, Lists.newArrayList(listener), service);
+
+ // Establish a connection
+ t4jClient.connect();
+ for (int threads = 0; threads < numProcessingThreads; threads++) {
+ // This must be called once per processing thread
+ t4jClient.process();
+ }
+ }
+
+ public void stop() {
+ t4jClient.stop();
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/resources/META-INF/LICENSE b/chatterbox-twitter/chatterbox-twitter-impl/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-twitter/chatterbox-twitter-impl/src/main/resources/META-INF/NOTICE b/chatterbox-twitter/chatterbox-twitter-impl/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..6ad51d8
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-impl/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+Twitter Connector :: Resource Adapter Implementation
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-twitter/chatterbox-twitter-knock-knock/pom.xml b/chatterbox-twitter/chatterbox-twitter-knock-knock/pom.xml
new file mode 100644
index 0000000..08d3425
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-knock-knock/pom.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-twitter-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-twitter-knock-knock</artifactId>
+ <packaging>war</packaging>
+ <name>Chatterbox :: Twitter :: Knock Knock Jokes</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-twitter-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-twitter-impl</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>apache-tomee</artifactId>
+ <version>${version.tomee}</version>
+ <classifier>plus</classifier>
+ <type>zip</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.openejb.maven</groupId>
+ <artifactId>tomee-maven-plugin</artifactId>
+ <version>${version.tomee}</version>
+ <configuration>
+ <tomeeVersion>${version.tomee}</tomeeVersion>
+ <tomeeClassifier>plus</tomeeClassifier>
+ <libs>
+ <lib>org.apache.tomee.chatterbox:chatterbox-twitter-api:${project.version}:jar</lib>
+ </libs>
+ <apps>
+ <app>org.apache.tomee.chatterbox:chatterbox-twitter-rar:${project.version}:rar</app>
+ </apps>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>tomee-plus-remote</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <tomee.version>${version.tomee}</tomee.version>
+ <tomee.classifier>plus</tomee.classifier>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <tomee.classifier>${tomee.classifier}</tomee.classifier>
+ <tomee.version>${tomee.version}</tomee.version>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>arquillian-tomee-remote</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.shrinkwrap.descriptors</groupId>
+ <artifactId>shrinkwrap-descriptors-impl-javaee</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.shrinkwrap.resolver</groupId>
+ <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
diff --git a/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/LICENSE b/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/NOTICE b/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..6a84c53
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+Twitter Connector :: Sample EJB jar
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/beans.xml b/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..09dcb26
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<beans/>
diff --git a/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/ejb-jar.xml b/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/ejb-jar.xml
new file mode 100644
index 0000000..54bc449
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-knock-knock/src/main/resources/META-INF/ejb-jar.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
+ version="3.1">
+ <display-name>telnet-connector-sample-ejb</display-name>
+</ejb-jar>
diff --git a/chatterbox-twitter/chatterbox-twitter-rar/pom.xml b/chatterbox-twitter/chatterbox-twitter-rar/pom.xml
new file mode 100644
index 0000000..191bd51
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-rar/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-twitter-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-twitter-rar</artifactId>
+ <packaging>rar</packaging>
+ <name>Chatterbox :: Twitter :: Resource Adapter</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-twitter-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/LICENSE b/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/NOTICE b/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/NOTICE
new file mode 100644
index 0000000..c285da9
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/NOTICE
@@ -0,0 +1,5 @@
+Twitter Connector :: Resource Adapter
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/ra.xml b/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/ra.xml
new file mode 100644
index 0000000..9005f2c
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-rar/src/main/rar/META-INF/ra.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<connector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/connector_1_7.xsd"
+ version="1.7">
+ <description>Twitter Resource Adapter</description>
+ <display-name>Twitter Resource Adapter</display-name>
+ <eis-type>Twitter Resource Adapter</eis-type>
+ <resourceadapter-version>1.0</resourceadapter-version>
+ <license>
+ <license-required>false</license-required>
+ </license>
+ <resourceadapter>
+ <resourceadapter-class>org.apache.tomee.chatterbox.twitter.adapter.TwitterResourceAdapter</resourceadapter-class>
+ <config-property>
+ <config-property-name>consumerKey</config-property-name>
+ <config-property-type>String</config-property-type>
+ <config-property-value></config-property-value>
+ </config-property>
+ <config-property>
+ <config-property-name>consumerSecret</config-property-name>
+ <config-property-type>String</config-property-type>
+ <config-property-value></config-property-value>
+ </config-property>
+ <config-property>
+ <config-property-name>accessToken</config-property-name>
+ <config-property-type>String</config-property-type>
+ <config-property-value></config-property-value>
+ </config-property>
+ <config-property>
+ <config-property-name>accessTokenSecret</config-property-name>
+ <config-property-type>String</config-property-type>
+ <config-property-value></config-property-value>
+ </config-property>
+ <outbound-resourceadapter>
+ <connection-definition>
+ <managedconnectionfactory-class>org.apache.tomee.chatterbox.twitter.adapter.TwitterManagedConnectionFactory
+ </managedconnectionfactory-class>
+ <connectionfactory-interface>TwitterConnectionFactory
+ </connectionfactory-interface>
+ <connectionfactory-impl-class>org.apache.tomee.chatterbox.twitter.adapter.TwitterConnectionFactoryImpl
+ </connectionfactory-impl-class>
+ <connection-interface>TwitterConnection</connection-interface>
+ <connection-impl-class>org.apache.tomee.chatterbox.twitter.adapter.TwitterConnectionImpl</connection-impl-class>
+ </connection-definition>
+ <transaction-support>NoTransaction</transaction-support>
+ <reauthentication-support>false</reauthentication-support>
+ </outbound-resourceadapter>
+ <inbound-resourceadapter>
+ <messageadapter>
+ <messagelistener>
+ <messagelistener-type>TwitterUpdates</messagelistener-type>
+ <activationspec>
+ <activationspec-class>org.apache.tomee.chatterbox.twitter.adapter.TwitterActivationSpec
+ </activationspec-class>
+ </activationspec>
+ </messagelistener>
+ </messageadapter>
+ </inbound-resourceadapter>
+ </resourceadapter>
+</connector>
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/pom.xml b/chatterbox-twitter/chatterbox-twitter-sample-war/pom.xml
new file mode 100644
index 0000000..401c3c5
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/pom.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-twitter-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-twitter-sample-war</artifactId>
+ <packaging>war</packaging>
+ <name>Chatterbox :: Twitter :: Sample WAR</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-twitter-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-twitter-impl</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>apache-tomee</artifactId>
+ <version>${version.tomee}</version>
+ <classifier>plus</classifier>
+ <type>zip</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.openejb.maven</groupId>
+ <artifactId>tomee-maven-plugin</artifactId>
+ <version>${version.tomee}</version>
+ <configuration>
+ <tomeeVersion>${version.tomee}</tomeeVersion>
+ <tomeeClassifier>plus</tomeeClassifier>
+ <libs>
+ <lib>org.apache.tomee.chatterbox:chatterbox-twitter-api:${project.version}:jar</lib>
+ </libs>
+ <apps>
+ <app>org.apache.tomee.chatterbox:chatterbox-twitter-rar:${project.version}:rar</app>
+ </apps>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>tomee-plus-remote</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <tomee.version>${version.tomee}</tomee.version>
+ <tomee.classifier>plus</tomee.classifier>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <tomee.classifier>${tomee.classifier}</tomee.classifier>
+ <tomee.version>${tomee.version}</tomee.version>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>arquillian-tomee-remote</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.shrinkwrap.descriptors</groupId>
+ <artifactId>shrinkwrap-descriptors-impl-javaee</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.shrinkwrap.resolver</groupId>
+ <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/FavoriteHashTags.java b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/FavoriteHashTags.java
new file mode 100644
index 0000000..0899280
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/FavoriteHashTags.java
@@ -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.
+ */
+package org.superbiz;
+
+import org.apache.tomee.chatterbox.twitter.api.Tweet;
+import org.apache.tomee.chatterbox.twitter.api.TweetParam;
+import org.apache.tomee.chatterbox.twitter.api.TwitterUpdates;
+import org.apache.tomee.chatterbox.twitter.api.UserParam;
+
+import javax.ejb.MessageDriven;
+import java.util.logging.Logger;
+
+@MessageDriven(name = "Status")
+public class FavoriteHashTags implements TwitterUpdates {
+
+ private final static Logger LOGGER = Logger.getLogger(FavoriteHashTags.class.getName());
+
+ @Tweet(".*#TomEE.*")
+ public String tomeeStatus(@TweetParam final String status, @UserParam final String user) {
+
+ LOGGER.info(String.format("New status: %s, by %s", status, user));
+
+ return "#TomEE is awesome";
+ }
+
+ @Tweet(".*#JavaLand.*")
+ public String javaLand(@TweetParam final String status, @UserParam final String user) {
+
+ LOGGER.info(String.format("New JavaOne status: %s, by %s", status, user));
+
+ return "#JavaLand is awesome! Where else can you see a session then ride a rollercoster?";
+ }
+
+ @Tweet(".*#JavaOne.*")
+ public String javaoneStatus(@TweetParam final String status, @UserParam final String user) {
+
+ LOGGER.info(String.format("New JavaOne status: %s, by %s", status, user));
+
+ return "#JavaOne is where the cool tech showcases";
+ }
+
+ @Tweet(".*#NightHacking.*")
+ public String nightHacking(@TweetParam final String status, @UserParam final String user) {
+
+ LOGGER.info(String.format("New JavaOne status: %s, by %s", status, user));
+
+ return "#NightHacking Stephen Chin is like an extremely technical version of the Fonz, with robots.";
+ }
+
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/KnockKnock.java b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/KnockKnock.java
new file mode 100644
index 0000000..da1f0d2
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/KnockKnock.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz;
+
+import org.apache.tomee.chatterbox.twitter.api.Response;
+import org.apache.tomee.chatterbox.twitter.api.Tweet;
+import org.apache.tomee.chatterbox.twitter.api.TweetParam;
+import org.apache.tomee.chatterbox.twitter.api.TwitterUpdates;
+import org.apache.tomee.chatterbox.twitter.api.UserParam;
+
+import javax.ejb.MessageDriven;
+
+@MessageDriven(name = "Status")
+public class KnockKnock implements TwitterUpdates {
+
+ @Tweet(".*KNOCK KNOCK.*")
+ public String loudKnock() {
+ return "Not so loud, you're giving me a headache!";
+ }
+
+ @Tweet(".*[Kk]nock(,? |-)[Kk]nock.*")
+ public Response knockKnock() {
+
+ return Response.message("Who's there?")
+ .dialog(new WhosThere())
+ .build();
+ }
+
+ public class WhosThere {
+
+ @Tweet("{who}")
+ public Response who(@TweetParam("who") final String who, @UserParam final String user) {
+ if (who.equals(user)) {
+ return Response.message("You know how knock knock jokes work, right?")
+ .build();
+ } else {
+ return Response.message(who + " who?")
+ .dialog(new Who())
+ .build();
+ }
+ }
+
+ @Tweet("(?i)Banana")
+ public Response orange() {
+ return Response.message("Orange you glad I didn't say Banana again. Try again, who's there?")
+ .dialog(this)
+ .build();
+ }
+ }
+
+ public class Who {
+
+ public String punchline() {
+ return "Haha, lol. That's a good one, I'll have to remember that.";
+ }
+ }
+
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/MathWiz.java b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/MathWiz.java
new file mode 100644
index 0000000..fc0c0d4
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/java/org/superbiz/MathWiz.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.superbiz;
+
+import org.apache.tomee.chatterbox.twitter.api.Tweet;
+import org.apache.tomee.chatterbox.twitter.api.TweetParam;
+import org.apache.tomee.chatterbox.twitter.api.TwitterUpdates;
+
+import javax.ejb.MessageDriven;
+
+@MessageDriven
+public class MathWiz implements TwitterUpdates {
+
+ @Tweet("(?i)what is 2 ?[*x] ?2")
+ public String twoTimesTwo() {
+ return "The same thing as 2 + 2";
+ }
+
+ @Tweet("(?i)what is {a} ?[*x] ?{b}")
+ public String times(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return String.format("%s times %s is %s", a, b, a * b);
+ }
+
+ @Tweet("(?i)what is {a} times {b}")
+ public String times2(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return times(a, b);
+ }
+
+ @Tweet("(?i)what is 2 ?+ ?2")
+ public String plus2() {
+ return "The same thing as 2 x 2";
+ }
+
+ @Tweet("(?i)what is {a} ?+ ?{b}")
+ public String plus(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return String.format("%s plus %s is %s", a, b, a + b);
+ }
+
+ @Tweet("(?i)what is {a} plus {b}")
+ public String plus2(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return plus(a, b);
+ }
+
+ @Tweet("(?i)what is {a} ?- ?{b}")
+ public String minus(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return String.format("%s minus %s is %s", a, b, a - b);
+ }
+
+ @Tweet("(?i)what is {a} minus {b}")
+ public String minus2(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return plus(a, b);
+ }
+
+ @Tweet("(?i)what is {a} ?/ ?{b}")
+ public String divided(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return String.format("%s divided by %s is %s", a, b, a / b);
+ }
+
+ @Tweet("(?i)what is {a} minus {b}")
+ public String divided2(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return plus(a, b);
+ }
+
+
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/LICENSE b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/NOTICE b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..ce68047
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+Twitter Connector :: Sample WAR
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/ejb-jar.xml b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/ejb-jar.xml
new file mode 100644
index 0000000..54bc449
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/main/resources/META-INF/ejb-jar.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
+ version="3.1">
+ <display-name>telnet-connector-sample-ejb</display-name>
+</ejb-jar>
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/connector/starter/Runner.java b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/connector/starter/Runner.java
new file mode 100644
index 0000000..e8b0a7e
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/connector/starter/Runner.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.connector.starter;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.ResourceAdapterArchive;
+import org.jboss.shrinkwrap.descriptor.api.Descriptors;
+import org.jboss.shrinkwrap.descriptor.api.connector10.ConfigProperty;
+import org.jboss.shrinkwrap.descriptor.api.connector10.ConnectorDescriptor;
+import org.jboss.shrinkwrap.descriptor.api.connector10.Resourceadapter;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeUnit;
+
+@RunWith(Arquillian.class)
+public class Runner {
+
+ @Deployment(testable = false)
+ public static EnterpriseArchive createDeployment() {
+ final JavaArchive apiJar = ShrinkWrap.create(JavaArchive.class, "api.jar");
+ apiJar.addPackages(true, "org.apache.tomee.chatterbox.connector.starter.api");
+ System.out.println(apiJar.toString(true));
+ System.out.println();
+
+ final JavaArchive rarLib = ShrinkWrap.create(JavaArchive.class, "lib.jar");
+ rarLib.addPackages(false,
+ "org.apache.tomee.chatterbox.connector.starter.adapter",
+ "org.apache.tomee.chatterbox.connector.starter.authenticator");
+
+ System.out.println(rarLib.toString(true));
+ System.out.println();
+
+ final ResourceAdapterArchive rar = ShrinkWrap.create(ResourceAdapterArchive.class, "test.rar");
+ rar.addAsLibraries(rarLib);
+
+ final ConnectorDescriptor raXml = Descriptors.create(ConnectorDescriptor.class);
+ final ConfigProperty<Resourceadapter<ConnectorDescriptor>> intervalProperty = raXml.getOrCreateResourceadapter().createConfigProperty();
+ intervalProperty.configPropertyName("interval");
+ intervalProperty.configPropertyType("int");
+ intervalProperty.configPropertyValue("15");
+
+ rar.setResourceAdapterXML(new StringAsset(raXml.exportAsString()));
+ System.out.println(rar.toString(true));
+ System.out.println();
+
+ final JavaArchive jar = ShrinkWrap.create(JavaArchive.class, "test.jar");
+ jar.addPackages(true, "org.superbiz");
+ System.out.println(jar.toString(true));
+ System.out.println();
+
+ // Make the EAR
+ final EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class, "test.ear")
+ .addAsModule(rar).addAsModule(jar).addAsLibraries(apiJar);
+ System.out.println(ear.toString(true));
+ System.out.println();
+
+ return ear;
+ }
+
+ @Test
+ public void run() {
+ try {
+ Thread.sleep(TimeUnit.HOURS.toMillis(1));
+ } catch (final InterruptedException e) {
+ Thread.interrupted();
+ }
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/StatusAdaptor.java b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/StatusAdaptor.java
new file mode 100644
index 0000000..d7b69d5
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/StatusAdaptor.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+
+import twitter4j.GeoLocation;
+import twitter4j.HashtagEntity;
+import twitter4j.MediaEntity;
+import twitter4j.Place;
+import twitter4j.RateLimitStatus;
+import twitter4j.Scopes;
+import twitter4j.Status;
+import twitter4j.SymbolEntity;
+import twitter4j.URLEntity;
+import twitter4j.User;
+import twitter4j.UserMentionEntity;
+
+import java.util.Date;
+
+public class StatusAdaptor implements Status {
+ @Override
+ public Date getCreatedAt() {
+ return null;
+ }
+
+ @Override
+ public long getId() {
+ return 0;
+ }
+
+ @Override
+ public String getText() {
+ return null;
+ }
+
+ @Override
+ public String getSource() {
+ return null;
+ }
+
+ @Override
+ public boolean isTruncated() {
+ return false;
+ }
+
+ @Override
+ public long getInReplyToStatusId() {
+ return 0;
+ }
+
+ @Override
+ public long getInReplyToUserId() {
+ return 0;
+ }
+
+ @Override
+ public String getInReplyToScreenName() {
+ return null;
+ }
+
+ @Override
+ public GeoLocation getGeoLocation() {
+ return null;
+ }
+
+ @Override
+ public Place getPlace() {
+ return null;
+ }
+
+ @Override
+ public boolean isFavorited() {
+ return false;
+ }
+
+ @Override
+ public boolean isRetweeted() {
+ return false;
+ }
+
+ @Override
+ public int getFavoriteCount() {
+ return 0;
+ }
+
+ @Override
+ public User getUser() {
+ return null;
+ }
+
+ @Override
+ public boolean isRetweet() {
+ return false;
+ }
+
+ @Override
+ public Status getRetweetedStatus() {
+ return null;
+ }
+
+ @Override
+ public long[] getContributors() {
+ return new long[0];
+ }
+
+ @Override
+ public int getRetweetCount() {
+ return 0;
+ }
+
+ @Override
+ public boolean isRetweetedByMe() {
+ return false;
+ }
+
+ @Override
+ public long getCurrentUserRetweetId() {
+ return 0;
+ }
+
+ @Override
+ public boolean isPossiblySensitive() {
+ return false;
+ }
+
+ @Override
+ public String getLang() {
+ return null;
+ }
+
+ @Override
+ public Scopes getScopes() {
+ return null;
+ }
+
+ @Override
+ public int compareTo(final Status o) {
+ return 0;
+ }
+
+ @Override
+ public UserMentionEntity[] getUserMentionEntities() {
+ return new UserMentionEntity[0];
+ }
+
+ @Override
+ public URLEntity[] getURLEntities() {
+ return new URLEntity[0];
+ }
+
+ @Override
+ public HashtagEntity[] getHashtagEntities() {
+ return new HashtagEntity[0];
+ }
+
+ @Override
+ public MediaEntity[] getMediaEntities() {
+ return new MediaEntity[0];
+ }
+
+ @Override
+ public SymbolEntity[] getSymbolEntities() {
+ return new SymbolEntity[0];
+ }
+
+ @Override
+ public RateLimitStatus getRateLimitStatus() {
+ return null;
+ }
+
+ @Override
+ public int getAccessLevel() {
+ return 0;
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/TestStatus.java b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/TestStatus.java
new file mode 100644
index 0000000..488cc65
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/TestStatus.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import twitter4j.User;
+
+public class TestStatus extends StatusAdaptor {
+
+ private final String text;
+ private final String user;
+
+ public TestStatus(final String text, final String jongallimore) {
+ this.text = text;
+ user = jongallimore;
+ }
+
+ @Override
+ public String getText() {
+ return text;
+ }
+
+ @Override
+ public User getUser() {
+ return new UserAdaptor() {
+ @Override
+ public String getScreenName() {
+ return user;
+ }
+ };
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterResourceAdapterTest.java b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterResourceAdapterTest.java
new file mode 100644
index 0000000..e84d85b
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/TwitterResourceAdapterTest.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import org.apache.tomee.chatterbox.twitter.api.InvokeAllMatches;
+import org.apache.tomee.chatterbox.twitter.api.Tweet;
+import org.apache.tomee.chatterbox.twitter.api.TweetParam;
+import org.apache.tomee.chatterbox.twitter.api.User;
+import org.apache.tomee.chatterbox.twitter.api.UserParam;
+import org.junit.Assert;
+import org.junit.Test;
+import org.superbiz.FavoriteHashTags;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.endpoint.MessageEndpoint;
+import java.lang.reflect.Method;
+import java.util.logging.Logger;
+
+public class TwitterResourceAdapterTest {
+
+ @Test
+ public void testShouldInvokeMdb() throws Exception {
+
+ final Class<?> clazz = TweetBean.class;
+ final TwitterResourceAdapter.EndpointTarget endpointTarget = new TwitterResourceAdapter().new EndpointTarget(new MyTweetBean(), clazz);
+
+ endpointTarget.invoke(new TestStatus("Testing connectors on #TomEE for #JavaOne", "jongallimore"));
+ }
+
+ @Test
+ public void valuesSimple() throws Exception {
+ final Object o = new Object() {
+ @Tweet("do you like {thing}\\?")
+ public String like(@TweetParam("thing") String thing) {
+ return "I'm not sure if I like " + thing;
+ }
+ };
+
+ final Method method = o.getClass().getMethod("like", String.class);
+ final Object[] values = TwitterResourceAdapter.getValues(method, new TestStatus("@Bot @Bot do you like candy?", "Joe"));
+
+ Assert.assertEquals(1, values.length);
+ Assert.assertEquals("candy", values[0]);
+ }
+
+ @Test
+ public void valuesBetweenSpaces() throws Exception {
+ final Object o = new Object() {
+ @Tweet("what is {a} ?[*x] ?{b}")
+ public String math(@TweetParam("a") int a, @TweetParam("b") int b) {
+ return null;
+ }
+ };
+
+ final Method method = o.getClass().getMethod("math", int.class, int.class);
+
+ {
+ final Object[] values = TwitterResourceAdapter.getValues(method, new TestStatus("what is 4 x 7", "Joe"));
+ Assert.assertEquals(2, values.length);
+ Assert.assertEquals(new Integer(4), values[0]);
+ Assert.assertEquals(new Integer(7), values[1]);
+ }
+ }
+
+
+ private static class MyTweetBean extends TweetBean implements MessageEndpoint {
+
+ @Override
+ public void beforeDelivery(final Method method) throws NoSuchMethodException, ResourceException {
+
+ }
+
+ @Override
+ public void afterDelivery() throws ResourceException {
+
+ }
+
+ @Override
+ public void release() {
+
+ }
+ }
+
+ @InvokeAllMatches
+ private static class TweetBean {
+
+ private final static Logger LOGGER = Logger.getLogger(FavoriteHashTags.class.getName());
+
+ @Tweet(".*#TomEE.*")
+ public void tomeeStatus(@TweetParam final String status, @UserParam final String user) {
+ LOGGER.info(String.format("New status: %s, by %s", status, user));
+ }
+
+ @Tweet(".*#JavaOne.*")
+ public void javaoneStatus(@TweetParam final String status, @UserParam final String user) {
+ LOGGER.info(String.format("New JavaOne status: %s, by %s", status, user));
+ }
+
+ @User(".*jongallimore.*")
+ public void asfStatus(@TweetParam final String status, @UserParam final String user) {
+ LOGGER.info(String.format("New ASF status: %s, by %s", status, user));
+ }
+ }
+
+
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/UserAdaptor.java b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/UserAdaptor.java
new file mode 100644
index 0000000..5887ab6
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/java/org/apache/tomee/chatterbox/twitter/adapter/UserAdaptor.java
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.twitter.adapter;
+
+import twitter4j.RateLimitStatus;
+import twitter4j.Status;
+import twitter4j.URLEntity;
+import twitter4j.User;
+
+import java.util.Date;
+
+public class UserAdaptor implements User {
+
+ @Override
+ public long getId() {
+ return 0;
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public String getScreenName() {
+ return null;
+ }
+
+ @Override
+ public String getLocation() {
+ return null;
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public boolean isContributorsEnabled() {
+ return false;
+ }
+
+ @Override
+ public String getProfileImageURL() {
+ return null;
+ }
+
+ @Override
+ public String getBiggerProfileImageURL() {
+ return null;
+ }
+
+ @Override
+ public String getMiniProfileImageURL() {
+ return null;
+ }
+
+ @Override
+ public String getOriginalProfileImageURL() {
+ return null;
+ }
+
+ @Override
+ public String getProfileImageURLHttps() {
+ return null;
+ }
+
+ @Override
+ public String getBiggerProfileImageURLHttps() {
+ return null;
+ }
+
+ @Override
+ public String getMiniProfileImageURLHttps() {
+ return null;
+ }
+
+ @Override
+ public String getOriginalProfileImageURLHttps() {
+ return null;
+ }
+
+ @Override
+ public String getURL() {
+ return null;
+ }
+
+ @Override
+ public boolean isProtected() {
+ return false;
+ }
+
+ @Override
+ public int getFollowersCount() {
+ return 0;
+ }
+
+ @Override
+ public Status getStatus() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBackgroundColor() {
+ return null;
+ }
+
+ @Override
+ public String getProfileTextColor() {
+ return null;
+ }
+
+ @Override
+ public String getProfileLinkColor() {
+ return null;
+ }
+
+ @Override
+ public String getProfileSidebarFillColor() {
+ return null;
+ }
+
+ @Override
+ public String getProfileSidebarBorderColor() {
+ return null;
+ }
+
+ @Override
+ public boolean isProfileUseBackgroundImage() {
+ return false;
+ }
+
+ @Override
+ public boolean isShowAllInlineMedia() {
+ return false;
+ }
+
+ @Override
+ public int getFriendsCount() {
+ return 0;
+ }
+
+ @Override
+ public Date getCreatedAt() {
+ return null;
+ }
+
+ @Override
+ public int getFavouritesCount() {
+ return 0;
+ }
+
+ @Override
+ public int getUtcOffset() {
+ return 0;
+ }
+
+ @Override
+ public String getTimeZone() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBackgroundImageURL() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBackgroundImageUrlHttps() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBannerURL() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBannerRetinaURL() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBannerIPadURL() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBannerIPadRetinaURL() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBannerMobileURL() {
+ return null;
+ }
+
+ @Override
+ public String getProfileBannerMobileRetinaURL() {
+ return null;
+ }
+
+ @Override
+ public boolean isProfileBackgroundTiled() {
+ return false;
+ }
+
+ @Override
+ public String getLang() {
+ return null;
+ }
+
+ @Override
+ public int getStatusesCount() {
+ return 0;
+ }
+
+ @Override
+ public boolean isGeoEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isVerified() {
+ return false;
+ }
+
+ @Override
+ public boolean isTranslator() {
+ return false;
+ }
+
+ @Override
+ public int getListedCount() {
+ return 0;
+ }
+
+ @Override
+ public boolean isFollowRequestSent() {
+ return false;
+ }
+
+ @Override
+ public URLEntity[] getDescriptionURLEntities() {
+ return new URLEntity[0];
+ }
+
+ @Override
+ public URLEntity getURLEntity() {
+ return null;
+ }
+
+ @Override
+ public int compareTo(final User o) {
+ return 0;
+ }
+
+ @Override
+ public RateLimitStatus getRateLimitStatus() {
+ return null;
+ }
+
+ @Override
+ public int getAccessLevel() {
+ return 0;
+ }
+}
diff --git a/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/resources/arquillian.xml b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..4141ac7
--- /dev/null
+++ b/chatterbox-twitter/chatterbox-twitter-sample-war/src/test/resources/arquillian.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<arquillian
+ >
+
+ <container qualifier="tomee" default="true">
+ <configuration>
+ <property name="classifier">plus</property>
+ <property name="httpPort">-1</property>
+ <property name="stopPort">-1</property>
+ <property name="ajpPort">-1</property>
+ </configuration>
+ </container>
+</arquillian>
diff --git a/chatterbox-twitter/pom.xml b/chatterbox-twitter/pom.xml
new file mode 100644
index 0000000..8f6f5c8
--- /dev/null
+++ b/chatterbox-twitter/pom.xml
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-twitter-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>0.3-SNAPSHOT</version>
+ <name>Chatterbox :: Twitter</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.arquillian>1.1.1.Final</version.arquillian>
+ <version.shrinkwrap.descriptor>2.0.0-alpha-5</version.shrinkwrap.descriptor>
+ <version.shrinkwrap.shrinkwrap>1.0.1</version.shrinkwrap.shrinkwrap>
+ <version.tomee>1.7.2</version.tomee>
+ <version.openejb>4.7.2</version.openejb>
+ <maven.checkstyle.plugin.version>2.16</maven.checkstyle.plugin.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <version>7.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.twitter</groupId>
+ <artifactId>hbc-core</artifactId>
+ <version>2.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.twitter4j</groupId>
+ <artifactId>twitter4j</artifactId>
+ <version>2.2.5</version>
+ </dependency>
+ <dependency>
+ <groupId>com.twitter</groupId>
+ <artifactId>hbc-twitter4j</artifactId>
+ <version>2.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ <version>1.1.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <modules>
+ <module>chatterbox-twitter-api</module>
+ <module>chatterbox-twitter-impl</module>
+ <module>chatterbox-twitter-rar</module>
+ <module>chatterbox-twitter-sample-war</module>
+ <module>chatterbox-twitter-knock-knock</module>
+ </modules>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>reserve-network-port</id>
+ <phase>process-test-classes</phase>
+ <goals>
+ <goal>reserve-network-port</goal>
+ </goals>
+ <configuration>
+ <portNames>
+ <portName>tomee.http.port</portName>
+ <portName>tomee.shutdown.port</portName>
+ </portNames>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-test-libs</id>
+ <phase>process-test-resources</phase>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </artifactItem>
+ </artifactItems>
+ <outputDirectory>
+ ${project.build.directory}/test-libs
+ </outputDirectory>
+ <stripVersion>true</stripVersion>
+ </configuration>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <optimize>true</optimize>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>tomee-plus-remote</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <tomee.version>${version.tomee}</tomee.version>
+ <tomee.classifier>plus</tomee.classifier>
+ </properties>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <tomee.classifier>${tomee.classifier}</tomee.classifier>
+ <tomee.version>${tomee.version}</tomee.version>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>arquillian-tomee-remote</artifactId>
+ <version>${tomee.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <version>${version.arquillian}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ <version>${version.arquillian}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.shrinkwrap.descriptors</groupId>
+ <artifactId>shrinkwrap-descriptors-impl-javaee</artifactId>
+ <version>${version.shrinkwrap.descriptor}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.shrinkwrap.resolver</groupId>
+ <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
+ <version>2.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>apache-tomee</artifactId>
+ <version>${tomee.version}</version>
+ <classifier>${tomee.classifier}</classifier>
+ <type>zip</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ </profile>
+ </profiles>
+</project>
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/pom.xml b/chatterbox-xmpp/chatterbox-xmpp-api/pom.xml
new file mode 100755
index 0000000..5ce8677
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-xmpp-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-xmpp-api</artifactId>
+ <packaging>jar</packaging>
+ <name>Chatterbox :: XMPP :: API</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.arquillian>1.1.1.Final</version.arquillian>
+ <version.shrinkwrap.descriptor>2.0.0-alpha-5</version.shrinkwrap.descriptor>
+ <version.shrinkwrap.shrinkwrap>1.0.1</version.shrinkwrap.shrinkwrap>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/MessageException.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/MessageException.java
new file mode 100755
index 0000000..f701e8b
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/MessageException.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.api;
+
+public class MessageException extends Exception {
+
+ public MessageException() {
+ }
+
+ public MessageException(String message) {
+ super(message);
+ }
+
+ public MessageException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public MessageException(Throwable cause) {
+ super(cause);
+ }
+
+ public MessageException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/XMPPConnection.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/XMPPConnection.java
new file mode 100755
index 0000000..cb463e1
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/XMPPConnection.java
@@ -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.
+ */
+
+package org.apache.tomee.chatterbox.xmpp.api;
+
+public interface XMPPConnection {
+ public void sendMessage(String recipient, String message) throws MessageException;
+
+ public void close();
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/XMPPConnectionFactory.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/XMPPConnectionFactory.java
new file mode 100755
index 0000000..dbef896
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/XMPPConnectionFactory.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.xmpp.api;
+
+import javax.resource.Referenceable;
+import javax.resource.ResourceException;
+import java.io.Serializable;
+
+public interface XMPPConnectionFactory extends Serializable, Referenceable {
+ public XMPPConnection getConnection() throws ResourceException;
+
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/InvokeAllMatches.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/InvokeAllMatches.java
new file mode 100644
index 0000000..fab44a2
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/InvokeAllMatches.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.api.inflow;
+
+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;
+
+@Inherited
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface InvokeAllMatches {
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/MessageText.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/MessageText.java
new file mode 100644
index 0000000..50885e0
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/MessageText.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.api.inflow;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface MessageText {
+ String value() default "";
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/MessageTextParam.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/MessageTextParam.java
new file mode 100644
index 0000000..db4ef8c
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/MessageTextParam.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.api.inflow;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface MessageTextParam {
+ String value() default "";
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/Sender.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/Sender.java
new file mode 100644
index 0000000..c7d8fa0
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/Sender.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.api.inflow;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Sender {
+ String value() default "";
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/SenderParam.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/SenderParam.java
new file mode 100644
index 0000000..9179249
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/SenderParam.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.api.inflow;
+
+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;
+
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface SenderParam {
+ String value() default "";
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/XMPPMessageListener.java b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/XMPPMessageListener.java
new file mode 100755
index 0000000..eb3228b
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-api/src/main/java/org/apache/tomee/chatterbox/xmpp/api/inflow/XMPPMessageListener.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.api.inflow;
+
+public interface XMPPMessageListener {
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/pom.xml b/chatterbox-xmpp/chatterbox-xmpp-impl/pom.xml
new file mode 100755
index 0000000..746f62d
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/pom.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-xmpp-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-xmpp-impl</artifactId>
+ <packaging>jar</packaging>
+ <name>Chatterbox :: XMPP :: Resource Adapter Implementation</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-xmpp-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>openejb-core</artifactId>
+ <version>${version.openejb}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.igniterealtime.smack</groupId>
+ <artifactId>smack-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.igniterealtime.smack</groupId>
+ <artifactId>smack-tcp</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>never</forkMode>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/Template.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/Template.java
new file mode 100644
index 0000000..e6b551f
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/Template.java
@@ -0,0 +1,387 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Template {
+
+ public static final String LIMITED_REGEX_SUFFIX = "(/.*)?";
+ public static final String FINAL_MATCH_GROUP = "FINAL_MATCH_GROUP";
+ private static final String DEFAULT_PATH_VARIABLE_REGEX = "([^/]+?)";
+ private static final String CHARACTERS_TO_ESCAPE = ".*+$()";
+
+ private final String template;
+ private final List<String> variables = new ArrayList<String>();
+ private final List<String> customVariables = new ArrayList<String>();
+ private final Pattern templateRegexPattern;
+ private final String literals;
+ private final List<UriChunk> uriChunks;
+
+ public Template(final String theTemplate) {
+ template = theTemplate;
+ final StringBuilder literalChars = new StringBuilder();
+ final StringBuilder patternBuilder = new StringBuilder();
+ final CurlyBraceTokenizer tok = new CurlyBraceTokenizer(template);
+ uriChunks = new ArrayList<>();
+ while (tok.hasNext()) {
+ final String templatePart = tok.next();
+ final UriChunk chunk = UriChunk.createUriChunk(templatePart);
+ uriChunks.add(chunk);
+ if (chunk instanceof Literal) {
+ final String substr = escapeCharacters(chunk.getValue());
+ literalChars.append(substr);
+ patternBuilder.append(substr);
+ } else if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ variables.add(var.getName());
+ if (var.getPattern() != null) {
+ customVariables.add(var.getName());
+ patternBuilder.append('(');
+ patternBuilder.append(var.getPattern());
+ patternBuilder.append(')');
+ } else {
+ patternBuilder.append(DEFAULT_PATH_VARIABLE_REGEX);
+ }
+ }
+ }
+ literals = literalChars.toString();
+
+ final int endPos = patternBuilder.length() - 1;
+ final boolean endsWithSlash = (endPos >= 0) && patternBuilder.charAt(endPos) == '/';
+ if (endsWithSlash) {
+ patternBuilder.deleteCharAt(endPos);
+ }
+ patternBuilder.append(LIMITED_REGEX_SUFFIX);
+
+ templateRegexPattern = Pattern.compile(patternBuilder.toString());
+ }
+
+ private static String escapeCharacters(final String expression) {
+ final StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < expression.length(); i++) {
+ final char ch = expression.charAt(i);
+ sb.append(isReservedCharacter(ch) ? "\\" + ch : ch);
+ }
+ return sb.toString();
+ }
+
+ private static boolean isReservedCharacter(final char ch) {
+ return CHARACTERS_TO_ESCAPE.indexOf(ch) != -1;
+ }
+
+ public String getLiteralChars() {
+ return literals;
+ }
+
+ public String getValue() {
+ return template;
+ }
+
+ public String getPatternValue() {
+ return templateRegexPattern.toString();
+ }
+
+ public List<String> getVariables() {
+ return Collections.unmodifiableList(variables);
+ }
+
+ public List<String> getCustomVariables() {
+ return Collections.unmodifiableList(customVariables);
+ }
+
+ public boolean match(final String uri, final Map<String, List<String>> templateVariableToValue) {
+
+ if (uri == null) {
+ return (templateRegexPattern == null);
+ }
+
+ if (templateRegexPattern == null) {
+ return false;
+ }
+
+ Matcher m = templateRegexPattern.matcher(uri);
+ if (!m.matches()) {
+ return false;
+ }
+
+ // Assign the matched template values to template variables
+ final int groupCount = m.groupCount();
+
+ int i = 1;
+ for (final String name : variables) {
+ while (i <= groupCount) {
+ final String value = m.group(i++);
+ if ((value == null || value.length() == 0 && i < groupCount)
+ && variables.size() + 1 < groupCount) {
+ continue;
+ }
+
+ if (templateVariableToValue.get(name) == null) {
+ templateVariableToValue.put(name, new ArrayList<>());
+ }
+
+ templateVariableToValue.get(name).add(value);
+ break;
+ }
+ }
+ // The right hand side value, might be used to further resolve
+ // sub-resources.
+
+ String finalGroup = m.group(groupCount);
+ if (finalGroup == null) {
+ finalGroup = "";
+ }
+
+ templateVariableToValue.put(FINAL_MATCH_GROUP, Collections.singletonList(finalGroup));
+ return true;
+ }
+
+ public String substitute(final List<String> values) throws IllegalArgumentException {
+ if (values == null) {
+ throw new IllegalArgumentException("values is null");
+ }
+ final Iterator<String> iter = values.iterator();
+ final StringBuilder sb = new StringBuilder();
+ for (final UriChunk chunk : uriChunks) {
+ if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ if (iter.hasNext()) {
+ final String value = iter.next();
+ if (!var.matches(value)) {
+ throw new IllegalArgumentException("Value '" + value + "' does not match variable "
+ + var.getName() + " with value "
+ + var.getPattern());
+ }
+ sb.append(value);
+ } else {
+ sb.append(var);
+ }
+ } else {
+ sb.append(chunk);
+ }
+ }
+ return sb.toString();
+ }
+
+ String substitute(final Map<String, ?> valuesMap) throws IllegalArgumentException {
+ return this.substitute(valuesMap, Collections.<String>emptySet(), false);
+ }
+
+ public String substitute(final Map<String, ?> valuesMap,
+ final Set<String> encodePathSlashVars,
+ final boolean allowUnresolved) throws IllegalArgumentException {
+ if (valuesMap == null) {
+ throw new IllegalArgumentException("valuesMap is null");
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (final UriChunk chunk : uriChunks) {
+ if (chunk instanceof Variable) {
+ final Variable var = (Variable) chunk;
+ final Object value = valuesMap.get(var.getName());
+ if (value != null) {
+ String sval = value.toString();
+ if (!var.matches(sval)) {
+ throw new IllegalArgumentException("Value '" + sval + "' does not match variable "
+ + var.getName() + " with value "
+ + var.getPattern());
+ }
+ if (encodePathSlashVars.contains(var.getName())) {
+ sval = sval.replaceAll("/", "%2F");
+ }
+ sb.append(sval);
+ } else if (allowUnresolved) {
+ sb.append(chunk);
+ } else {
+ throw new IllegalArgumentException("Template variable " + var.getName()
+ + " has no matching value");
+ }
+ } else {
+ sb.append(chunk);
+ }
+ }
+ return sb.toString();
+ }
+
+ private abstract static class UriChunk {
+ public static UriChunk createUriChunk(final String uriChunk) {
+ if (uriChunk == null || "".equals(uriChunk)) {
+ throw new IllegalArgumentException("uriChunk is empty");
+ }
+ UriChunk uriChunkRepresentation = Variable.create(uriChunk);
+ if (uriChunkRepresentation == null) {
+ uriChunkRepresentation = Literal.create(uriChunk);
+ }
+ return uriChunkRepresentation;
+ }
+
+ public abstract String getValue();
+
+ @Override
+ public String toString() {
+ return getValue();
+ }
+ }
+
+ private static final class Literal extends UriChunk {
+ private String value;
+
+ private Literal() {
+ // empty constructor
+ }
+
+ public static Literal create(final String uriChunk) {
+ if (uriChunk == null || "".equals(uriChunk)) {
+ throw new IllegalArgumentException("uriChunk is empty");
+ }
+ final Literal literal = new Literal();
+ literal.value = uriChunk;
+ return literal;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ }
+
+ private static final class Variable extends UriChunk {
+ private static final Pattern VARIABLE_PATTERN = Pattern.compile("(\\w[-\\w\\.]*[ ]*)(\\:(.+))?");
+ private String name;
+ private Pattern pattern;
+
+ private Variable() {
+ // empty constructor
+ }
+
+ public static Variable create(String uriChunk) {
+ final Variable newVariable = new Variable();
+ if (uriChunk == null || "".equals(uriChunk)) {
+ return null;
+ }
+ if (CurlyBraceTokenizer.insideBraces(uriChunk)) {
+ uriChunk = CurlyBraceTokenizer.stripBraces(uriChunk).trim();
+ final Matcher matcher = VARIABLE_PATTERN.matcher(uriChunk);
+ if (matcher.matches()) {
+ newVariable.name = matcher.group(1).trim();
+ if (matcher.group(2) != null && matcher.group(3) != null) {
+ final String patternExpression = matcher.group(3).trim();
+ newVariable.pattern = Pattern.compile(patternExpression);
+ }
+ return newVariable;
+ }
+ }
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPattern() {
+ return pattern != null ? pattern.pattern() : null;
+ }
+
+ public boolean matches(final String value) {
+ if (pattern == null) {
+ return true;
+ } else {
+ return pattern.matcher(value).matches();
+ }
+ }
+
+ @Override
+ public String getValue() {
+ if (pattern != null) {
+ return "{" + name + ":" + pattern + "}";
+ } else {
+ return "{" + name + "}";
+ }
+ }
+ }
+
+ static class CurlyBraceTokenizer {
+
+ private final List<String> tokens = new ArrayList<String>();
+ private int tokenIdx;
+
+ CurlyBraceTokenizer(final String string) {
+ boolean outside = true;
+ int level = 0;
+ int lastIdx = 0;
+ int idx;
+ for (idx = 0; idx < string.length(); idx++) {
+ if (string.charAt(idx) == '{') {
+ if (outside) {
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx));
+ }
+ lastIdx = idx;
+ outside = false;
+ } else {
+ level++;
+ }
+ } else if (string.charAt(idx) == '}' && !outside) {
+ if (level > 0) {
+ level--;
+ } else {
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx + 1));
+ }
+ lastIdx = idx + 1;
+ outside = true;
+ }
+ }
+ }
+ if (lastIdx < idx) {
+ tokens.add(string.substring(lastIdx, idx));
+ }
+ }
+
+ public static boolean insideBraces(final String token) {
+ return token.charAt(0) == '{' && token.charAt(token.length() - 1) == '}';
+ }
+
+ public static String stripBraces(final String token) {
+ if (insideBraces(token)) {
+ return token.substring(1, token.length() - 1);
+ } else {
+ return token;
+ }
+ }
+
+ public boolean hasNext() {
+ return tokens.size() > tokenIdx;
+ }
+
+ public String next() {
+ if (hasNext()) {
+ return tokens.get(tokenIdx++);
+ } else {
+ throw new IllegalStateException("no more elements");
+ }
+ }
+ }
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPActivation.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPActivation.java
new file mode 100755
index 0000000..18e66b9
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPActivation.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import org.apache.tomee.chatterbox.xmpp.impl.inflow.XMPPActivationSpec;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+
+public class XMPPActivation {
+
+ private XMPPResourceAdapter ra;
+
+ private XMPPActivationSpec spec;
+
+ private MessageEndpointFactory endpointFactory;
+
+ public XMPPActivation() throws ResourceException {
+ this(null, null, null);
+ }
+
+ public XMPPActivation(XMPPResourceAdapter ra,
+ MessageEndpointFactory endpointFactory,
+ XMPPActivationSpec spec) throws ResourceException {
+ this.ra = ra;
+ this.endpointFactory = endpointFactory;
+ this.spec = spec;
+ }
+
+ public XMPPActivationSpec getActivationSpec() {
+ return spec;
+ }
+
+ public MessageEndpointFactory getMessageEndpointFactory() {
+ return endpointFactory;
+ }
+
+ public void start() throws ResourceException {
+
+ }
+
+ public void stop() {
+
+ }
+
+
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPConnectionFactoryImpl.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPConnectionFactoryImpl.java
new file mode 100755
index 0000000..ef743a4
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPConnectionFactoryImpl.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import org.apache.tomee.chatterbox.xmpp.api.XMPPConnection;
+import org.apache.tomee.chatterbox.xmpp.api.XMPPConnectionFactory;
+
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import java.util.logging.Logger;
+
+public class XMPPConnectionFactoryImpl implements XMPPConnectionFactory {
+ private static final long serialVersionUID = 1L;
+
+ private static Logger log = Logger.getLogger(XMPPConnectionFactoryImpl.class.getName());
+
+ private Reference reference;
+
+ private XMPPManagedConnectionFactory mcf;
+
+ private ConnectionManager connectionManager;
+
+ public XMPPConnectionFactoryImpl() {
+
+ }
+
+ public XMPPConnectionFactoryImpl(XMPPManagedConnectionFactory mcf, ConnectionManager cxManager) {
+ this.mcf = mcf;
+ this.connectionManager = cxManager;
+ }
+
+ @Override
+ public XMPPConnection getConnection() throws ResourceException {
+ log.finest("getConnection()");
+ return (XMPPConnection) connectionManager.allocateConnection(mcf, null);
+ }
+
+ @Override
+ public Reference getReference() throws NamingException {
+ log.finest("getReference()");
+ return reference;
+ }
+
+ @Override
+ public void setReference(Reference reference) {
+ log.finest("setReference()");
+ this.reference = reference;
+ }
+
+
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPConnectionImpl.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPConnectionImpl.java
new file mode 100755
index 0000000..1cc7631
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPConnectionImpl.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import org.apache.tomee.chatterbox.xmpp.api.MessageException;
+import org.apache.tomee.chatterbox.xmpp.api.XMPPConnection;
+
+import java.util.logging.Logger;
+
+public class XMPPConnectionImpl implements XMPPConnection {
+ private static Logger log = Logger.getLogger(XMPPConnectionImpl.class.getName());
+
+ private XMPPManagedConnection mc;
+
+ private XMPPManagedConnectionFactory mcf;
+
+ public XMPPConnectionImpl(XMPPManagedConnection mc, XMPPManagedConnectionFactory mcf) {
+ this.mc = mc;
+ this.mcf = mcf;
+ }
+
+ public void sendMessage(String recipient, String message) throws MessageException {
+ mc.sendMessage(recipient, message);
+ }
+
+ public void close() {
+ mc.closeHandle(this);
+ }
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnection.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnection.java
new file mode 100755
index 0000000..0e81864
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnection.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import org.apache.tomee.chatterbox.xmpp.api.MessageException;
+import org.apache.tomee.chatterbox.xmpp.api.XMPPConnection;
+
+import javax.resource.NotSupportedException;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionEvent;
+import javax.resource.spi.ConnectionEventListener;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.LocalTransaction;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionMetaData;
+import javax.security.auth.Subject;
+import javax.transaction.xa.XAResource;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class XMPPManagedConnection implements ManagedConnection {
+
+ private static Logger log = Logger.getLogger(XMPPManagedConnection.class.getName());
+
+ private PrintWriter logwriter;
+
+ private XMPPManagedConnectionFactory mcf;
+
+ private List<ConnectionEventListener> listeners;
+
+ private XMPPConnectionImpl connection;
+
+ public XMPPManagedConnection(XMPPManagedConnectionFactory mcf) {
+ this.mcf = mcf;
+ this.logwriter = null;
+ this.listeners = Collections.synchronizedList(new ArrayList<ConnectionEventListener>(1));
+ this.connection = null;
+ }
+
+ public Object getConnection(Subject subject,
+ ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("getConnection()");
+ connection = new XMPPConnectionImpl(this, mcf);
+ return connection;
+ }
+
+ public void associateConnection(Object connection) throws ResourceException {
+ log.finest("associateConnection()");
+
+ if (connection == null)
+ throw new ResourceException("Null connection handle");
+
+ if (!(connection instanceof XMPPConnectionImpl))
+ throw new ResourceException("Wrong connection handle");
+
+ this.connection = (XMPPConnectionImpl) connection;
+ }
+
+ public void cleanup() throws ResourceException {
+ log.finest("cleanup()");
+ }
+
+ public void destroy() throws ResourceException {
+ log.finest("destroy()");
+ }
+
+ public void addConnectionEventListener(ConnectionEventListener listener) {
+ log.finest("addConnectionEventListener()");
+
+ if (listener == null) {
+ throw new IllegalArgumentException("Listener is null");
+ }
+
+ listeners.add(listener);
+ }
+
+ public void removeConnectionEventListener(ConnectionEventListener listener) {
+ log.finest("removeConnectionEventListener()");
+ if (listener == null)
+ throw new IllegalArgumentException("Listener is null");
+ listeners.remove(listener);
+ }
+
+ void closeHandle(XMPPConnection handle) {
+ ConnectionEvent event = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
+ event.setConnectionHandle(handle);
+ for (ConnectionEventListener cel : listeners) {
+ cel.connectionClosed(event);
+ }
+ }
+
+ public PrintWriter getLogWriter() throws ResourceException {
+ log.finest("getLogWriter()");
+ return logwriter;
+ }
+
+ public void setLogWriter(PrintWriter out) throws ResourceException {
+ log.finest("setLogWriter()");
+ logwriter = out;
+ }
+
+ public LocalTransaction getLocalTransaction() throws ResourceException {
+ throw new NotSupportedException("getLocalTransaction() not supported");
+ }
+
+ public XAResource getXAResource() throws ResourceException {
+ throw new NotSupportedException("getXAResource() not supported");
+ }
+
+ public ManagedConnectionMetaData getMetaData() throws ResourceException {
+ log.finest("getMetaData()");
+ return new XMPPManagedConnectionMetaData();
+ }
+
+ void sendMessage(String recipient, String message) throws MessageException {
+ log.finest("sendMessage()");
+
+ final XMPPResourceAdapter resourceAdapter = (XMPPResourceAdapter) mcf.getResourceAdapter();
+ resourceAdapter.sendXMPPMessage(recipient, message);
+ }
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnectionFactory.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnectionFactory.java
new file mode 100755
index 0000000..d848bae
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnectionFactory.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import org.apache.tomee.chatterbox.xmpp.api.XMPPConnection;
+import org.apache.tomee.chatterbox.xmpp.api.XMPPConnectionFactory;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionDefinition;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterAssociation;
+import javax.security.auth.Subject;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Logger;
+
+@ConnectionDefinition(connectionFactory = XMPPConnectionFactory.class,
+ connectionFactoryImpl = XMPPConnectionFactoryImpl.class,
+ connection = XMPPConnection.class,
+ connectionImpl = XMPPConnectionImpl.class)
+public class XMPPManagedConnectionFactory implements ManagedConnectionFactory, ResourceAdapterAssociation {
+
+ private static final long serialVersionUID = 1L;
+
+ private static Logger log = Logger.getLogger(XMPPManagedConnectionFactory.class.getName());
+
+ private ResourceAdapter ra;
+
+ private PrintWriter logwriter;
+
+ public XMPPManagedConnectionFactory() {
+
+ }
+
+ public Object createConnectionFactory(ConnectionManager cxManager) throws ResourceException {
+ log.finest("createConnectionFactory()");
+ return new XMPPConnectionFactoryImpl(this, cxManager);
+ }
+
+ public Object createConnectionFactory() throws ResourceException {
+ throw new ResourceException("This resource adapter doesn't support non-managed environments");
+ }
+
+ public ManagedConnection createManagedConnection(Subject subject,
+ ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("createManagedConnection()");
+ return new XMPPManagedConnection(this);
+ }
+
+ public ManagedConnection matchManagedConnections(Set connectionSet,
+ Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException {
+ log.finest("matchManagedConnections()");
+ ManagedConnection result = null;
+ Iterator it = connectionSet.iterator();
+ while (result == null && it.hasNext()) {
+ ManagedConnection mc = (ManagedConnection) it.next();
+ if (mc instanceof XMPPManagedConnection) {
+ result = mc;
+ }
+
+ }
+ return result;
+ }
+
+ public PrintWriter getLogWriter() throws ResourceException {
+ log.finest("getLogWriter()");
+ return logwriter;
+ }
+
+ public void setLogWriter(PrintWriter out) throws ResourceException {
+ log.finest("setLogWriter()");
+ logwriter = out;
+ }
+
+ public ResourceAdapter getResourceAdapter() {
+ log.finest("getResourceAdapter()");
+ return ra;
+ }
+
+ public void setResourceAdapter(ResourceAdapter ra) {
+ log.finest("setResourceAdapter()");
+ this.ra = ra;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null)
+ return false;
+ if (other == this)
+ return true;
+ if (!(other instanceof XMPPManagedConnectionFactory))
+ return false;
+ boolean result = true;
+ return result;
+ }
+
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnectionMetaData.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnectionMetaData.java
new file mode 100755
index 0000000..c48a830
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPManagedConnectionMetaData.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnectionMetaData;
+import java.util.logging.Logger;
+
+public class XMPPManagedConnectionMetaData implements ManagedConnectionMetaData {
+
+ private static Logger log = Logger.getLogger(XMPPManagedConnectionMetaData.class.getName());
+
+ public XMPPManagedConnectionMetaData() {
+
+ }
+
+ @Override
+ public String getEISProductName() throws ResourceException {
+ log.finest("getEISProductName()");
+ return null; //TODO
+ }
+
+ @Override
+ public String getEISProductVersion() throws ResourceException {
+ log.finest("getEISProductVersion()");
+ return null; //TODO
+ }
+
+ @Override
+ public int getMaxConnections() throws ResourceException {
+ log.finest("getMaxConnections()");
+ return 0; //TODO
+ }
+
+ @Override
+ public String getUserName() throws ResourceException {
+ log.finest("getUserName()");
+ return null; //TODO
+ }
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPRaMetaData.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPRaMetaData.java
new file mode 100755
index 0000000..ef4fc7a
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPRaMetaData.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import javax.resource.cci.ResourceAdapterMetaData;
+
+public class XMPPRaMetaData implements ResourceAdapterMetaData {
+
+ public XMPPRaMetaData() {
+ }
+
+ @Override
+ public String getAdapterVersion() {
+ return "1.0";
+ }
+
+ @Override
+ public String getAdapterVendorName() {
+ return "Apache Software Foundation";
+ }
+
+ @Override
+ public String getAdapterName() {
+ return "XMPP Connector";
+ }
+
+ @Override
+ public String getAdapterShortDescription() {
+ return "Connects to XMPP server";
+ }
+
+ @Override
+ public String getSpecVersion() {
+ return "1.0";
+ }
+
+ @Override
+ public String[] getInteractionSpecsSupported() {
+ return null;
+ }
+
+ @Override
+ public boolean supportsExecuteWithInputAndOutputRecord() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsExecuteWithInputRecordOnly() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsLocalTransactionDemarcation() {
+ return false;
+ }
+
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPResourceAdapter.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPResourceAdapter.java
new file mode 100755
index 0000000..7887fc5
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/XMPPResourceAdapter.java
@@ -0,0 +1,458 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl;
+
+import org.apache.tomee.chatterbox.xmpp.api.MessageException;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.InvokeAllMatches;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.MessageText;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.MessageTextParam;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.Sender;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.SenderParam;
+import org.apache.tomee.chatterbox.xmpp.impl.inflow.XMPPActivationSpec;
+import org.jivesoftware.smack.Chat;
+import org.jivesoftware.smack.ChatManager;
+import org.jivesoftware.smack.ChatManagerListener;
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.MessageListener;
+import org.jivesoftware.smack.SmackException;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.packet.Presence;
+import org.jivesoftware.smack.tcp.XMPPTCPConnection;
+import org.tomitribe.util.editor.Converter;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.BootstrapContext;
+import javax.resource.spi.ConfigProperty;
+import javax.resource.spi.Connector;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterInternalException;
+import javax.resource.spi.TransactionSupport;
+import javax.resource.spi.endpoint.MessageEndpoint;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.transaction.xa.XAResource;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+@Connector(
+ reauthenticationSupport = false,
+ transactionSupport = TransactionSupport.TransactionSupportLevel.NoTransaction,
+ displayName = "XMPPConnector", vendorName = "Apache Software Foundation", version = "1.0")
+public class XMPPResourceAdapter implements ResourceAdapter, Serializable, MessageListener, ChatManagerListener {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Logger LOGGER = Logger.getLogger(XMPPResourceAdapter.class.getName());
+
+ final Map<XMPPActivationSpec, EndpointTarget> targets = new ConcurrentHashMap<XMPPActivationSpec, EndpointTarget>();
+
+ @ConfigProperty(defaultValue = "localhost")
+ private String host;
+
+ @ConfigProperty(defaultValue = "5222")
+ private Integer port;
+
+ @ConfigProperty
+ private String username;
+
+ @ConfigProperty
+ private String password;
+
+ @ConfigProperty
+ private String serviceName;
+
+ private XMPPTCPConnection connection;
+ private ChatManager chatmanager;
+ private boolean connected = false;
+
+ private static Object[] getValues(final Method method, final String sender, final String message) {
+
+ if (method == null) {
+ return null;
+ }
+
+ final Parameter[] parameters = method.getParameters();
+ if (parameters.length == 0) {
+ return new Object[0];
+ }
+
+ final Template senderTemplate = getTemplate(method.getAnnotation(Sender.class));
+ final Map<String, List<String>> senderParamValues = new HashMap<>();
+ if (senderTemplate != null) {
+ senderTemplate.match(sender, senderParamValues);
+ }
+
+ final Template messageTextTemplate = getTemplate(method.getAnnotation(MessageText.class));
+ final Map<String, List<String>> messageTextParamValues = new HashMap<>();
+ if (messageTextTemplate != null) {
+ messageTextTemplate.match(message, messageTextParamValues);
+ }
+
+ final Object[] values = new Object[parameters.length];
+
+ for (int i = 0; i < parameters.length; i++) {
+ final Parameter parameter = parameters[i];
+
+ values[i] = null;
+
+ if (parameter.isAnnotationPresent(SenderParam.class)) {
+ final SenderParam senderParam = parameter.getAnnotation(SenderParam.class);
+ if (senderParam.value() == null || senderParam.value().length() == 0) {
+ values[i] = Converter.convert(sender, parameter.getType(), null);
+ } else {
+ final List<String> paramValues = senderParamValues.get(senderParam.value());
+ final String paramValue = paramValues == null || paramValues.size() == 0 ? null : paramValues.get(0);
+ values[i] = Converter.convert(paramValue, parameter.getType(), null);
+ }
+ }
+
+ if (parameter.isAnnotationPresent(MessageTextParam.class)) {
+ final MessageTextParam messageTextParam = parameter.getAnnotation(MessageTextParam.class);
+ if (messageTextParam.value() == null || messageTextParam.value().length() == 0) {
+ values[i] = Converter.convert(message, parameter.getType(), null);
+ } else {
+ final List<String> paramValues = messageTextParamValues.get(messageTextParam.value());
+ final String paramValue = paramValues == null || paramValues.size() == 0 ? null : paramValues.get(0);
+ values[i] = Converter.convert(paramValue, parameter.getType(), null);
+ }
+ }
+ }
+
+ return values;
+ }
+
+ private static Template getTemplate(final Annotation annotation) {
+ if (annotation == null) {
+ return null;
+ }
+
+ try {
+
+ final Method patternMethod = annotation.getClass().getMethod("value");
+ if (patternMethod == null) {
+ return null;
+ }
+
+ if (!String.class.equals(patternMethod.getReturnType())) {
+ return null;
+ }
+
+ final String pattern = (String) patternMethod.invoke(annotation);
+ return new Template(pattern);
+ } catch (final Exception e) {
+ // ignore
+ }
+
+ return null;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public Integer getPort() {
+ return port;
+ }
+
+ public void setPort(Integer port) {
+ this.port = port;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public void endpointActivation(final MessageEndpointFactory messageEndpointFactory, final ActivationSpec activationSpec)
+ throws ResourceException {
+ final XMPPActivationSpec xmppActivationSpec = (XMPPActivationSpec) activationSpec;
+ final MessageEndpoint messageEndpoint = messageEndpointFactory.createEndpoint(null);
+
+ final Class<?> endpointClass = xmppActivationSpec.getBeanClass() != null ? xmppActivationSpec
+ .getBeanClass() : messageEndpointFactory.getEndpointClass();
+
+ final EndpointTarget target = new EndpointTarget(messageEndpoint, endpointClass);
+ targets.put(xmppActivationSpec, target);
+
+ }
+
+ public void endpointDeactivation(final MessageEndpointFactory messageEndpointFactory, final ActivationSpec activationSpec) {
+ final XMPPActivationSpec xmppActivationSpec = (XMPPActivationSpec) activationSpec;
+
+ final EndpointTarget endpointTarget = targets.get(xmppActivationSpec);
+ if (endpointTarget == null) {
+ throw new IllegalStateException("No EndpointTarget to undeploy for ActivationSpec " + activationSpec);
+ }
+
+ endpointTarget.messageEndpoint.release();
+ }
+
+ public void start(BootstrapContext ctx)
+ throws ResourceAdapterInternalException {
+ LOGGER.info("Starting " + this);
+ connect();
+ }
+
+ public void stop() {
+ LOGGER.info("Stopping " + this);
+ disconnect();
+ }
+
+ public void connect() {
+ ConnectionConfiguration connConfig = new ConnectionConfiguration(host, port, serviceName);
+ connection = new XMPPTCPConnection(connConfig);
+
+ try {
+ connection.connect();
+ LOGGER.finest("Connected to " + host + ":" + port + "/" + serviceName);
+ } catch (XMPPException | SmackException | IOException e) {
+ LOGGER.log(Level.SEVERE, "Unable to connect to " + host + ":" + port + "/" + serviceName, e);
+ }
+
+ try {
+ connection.login(username, password);
+ LOGGER.finest("Logged in as " + username);
+
+ Presence presence = new Presence(Presence.Type.available);
+ connection.sendPacket(presence);
+
+ } catch (XMPPException | SmackException | IOException e) {
+ LOGGER.log(Level.SEVERE, "Unable to login as " + username, e);
+ }
+
+ connected = true;
+ chatmanager = ChatManager.getInstanceFor(connection);
+ chatmanager.addChatListener(this);
+ }
+
+ public void disconnect() {
+ try {
+ if (connected) {
+ chatmanager.removeChatListener(this);
+ connection.disconnect(new Presence(Presence.Type.unavailable));
+ }
+ } catch (SmackException.NotConnectedException e) {
+ LOGGER.log(Level.SEVERE, "Unable to logout", e);
+ }
+
+ connection = null;
+ chatmanager = null;
+ connected = false;
+
+ }
+
+ public void sendXMPPMessage(String recipient, String message) throws MessageException {
+ Chat newChat = chatmanager.createChat(recipient, this);
+
+ try {
+ newChat.sendMessage(message);
+ } catch (XMPPException | SmackException.NotConnectedException e) {
+ throw new MessageException(e);
+ }
+ }
+
+ public XAResource[] getXAResources(ActivationSpec[] specs)
+ throws ResourceException {
+ LOGGER.finest("getXAResources()");
+ return null;
+ }
+
+ @Override
+ public void processMessage(Chat chat, Message message) {
+
+ for (EndpointTarget endpointTarget : targets.values()) {
+ endpointTarget.invoke(chat, message);
+ }
+
+ chat.removeMessageListener(this);
+ chat.close();
+ }
+
+ @Override
+ public void chatCreated(Chat chat, boolean b) {
+ chat.addMessageListener(this);
+ }
+
+ @Override
+ public String toString() {
+ return "XMPPResourceAdapter{" +
+ "host='" + host + '\'' +
+ ", port=" + port +
+ ", username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ ", serviceName='" + serviceName + '\'' +
+ '}';
+ }
+
+ public static class EndpointTarget {
+ private final MessageEndpoint messageEndpoint;
+ private final Class<?> clazz;
+
+ public EndpointTarget(final MessageEndpoint messageEndpoint, final Class<?> clazz) {
+ this.messageEndpoint = messageEndpoint;
+ this.clazz = clazz;
+ }
+
+ public void invoke(Chat chat, Message message) {
+
+ // This method will be invoked essentially each keystroke made by the remote user
+ // We don't need to bother with this delivery logic until the user has pressed enter
+ // and fully sent the message.
+ if (message.getBody() == null) return;
+
+ // This chat message object exists for clean logging.
+ final ChatMessage chatMessage = new ChatMessage(chat, message);
+
+ // find matching method(s)
+
+ final List<Method> matchingMethods =
+ Arrays.asList(clazz.getDeclaredMethods())
+ .stream()
+ .sorted((m1, m2) -> m1.toString().compareTo(m2.toString()))
+ .filter(this::isPublic)
+ .filter(this::isNotFinal)
+ .filter(this::isNotAbstract)
+ .filter(m -> filterSender(chat.getParticipant(), m))
+ .filter(m -> filterMessage(message.getBody(), m))
+ .collect(Collectors.toList());
+
+ if (matchingMethods == null || matchingMethods.size() == 0) {
+ LOGGER.log(Level.INFO, "No method to match " + chatMessage);
+ return;
+ }
+
+ if (this.clazz.isAnnotationPresent(InvokeAllMatches.class)) {
+ for (final Method method : matchingMethods) {
+ LOGGER.log(Level.INFO, "Invoking method " + method.toString() + " for " + chatMessage);
+ invoke(method, chat.getParticipant(), message.getBody());
+ }
+ } else {
+ final Method method = matchingMethods.get(0);
+ LOGGER.log(Level.INFO, "Invoking method " + method.toString() + " for " + chatMessage);
+ invoke(method, chat.getParticipant(), message.getBody());
+ }
+ }
+
+ private boolean filterMessage(final String message, final Method m) {
+ return !m.isAnnotationPresent(MessageText.class) || "".equals(m.getAnnotation(MessageText.class).value())
+ || templateMatches(m.getAnnotation(MessageText.class).value(), message);
+ }
+
+ private boolean filterSender(final String sender, final Method m) {
+ return !m.isAnnotationPresent(Sender.class) || "".equals(m.getAnnotation(Sender.class).value())
+ || templateMatches(m.getAnnotation(Sender.class).value(), sender);
+ }
+
+ private boolean templateMatches(final String pattern, final String input) {
+ try {
+ if (Pattern.matches(pattern, input)) {
+ return true;
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+
+ final Template template = new Template(pattern);
+ final Map<String, List<String>> values = new HashMap<>();
+ return template.match(input, values);
+ }
+
+ private boolean isPublic(final Method m) {
+ return Modifier.isPublic(m.getModifiers());
+ }
+
+ private boolean isNotAbstract(final Method m) {
+ return !Modifier.isAbstract(m.getModifiers());
+ }
+
+ private boolean isNotFinal(final Method m) {
+ return !Modifier.isFinal(m.getModifiers());
+ }
+
+ private void invoke(final Method method, final String sender, final String message) {
+ try {
+ try {
+ messageEndpoint.beforeDelivery(method);
+ final Object[] values = getValues(method, sender, message);
+ method.invoke(messageEndpoint, values);
+ } finally {
+ messageEndpoint.afterDelivery();
+ }
+ } catch (final NoSuchMethodException | ResourceException | IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static class ChatMessage {
+ private final String sender;
+ private final String text;
+
+ public ChatMessage(Chat chat, Message message) {
+ this.sender = chat.getParticipant();
+ this.text = message.getBody();
+ }
+
+ @Override
+ public String toString() {
+ return "ChatMessage{" +
+ "sender='" + sender + '\'' +
+ ", text='" + text + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/inflow/XMPPActivationSpec.java b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/inflow/XMPPActivationSpec.java
new file mode 100755
index 0000000..c39c472
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-impl/src/main/java/org/apache/tomee/chatterbox/xmpp/impl/inflow/XMPPActivationSpec.java
@@ -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.
+ */
+package org.apache.tomee.chatterbox.xmpp.impl.inflow;
+
+import org.apache.tomee.chatterbox.xmpp.api.inflow.XMPPMessageListener;
+
+import javax.resource.spi.Activation;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.InvalidPropertyException;
+import javax.resource.spi.ResourceAdapter;
+import java.util.logging.Logger;
+
+@Activation(messageListeners = {XMPPMessageListener.class})
+public class XMPPActivationSpec implements ActivationSpec {
+
+ private static Logger log = Logger.getLogger(XMPPActivationSpec.class.getName());
+
+ private ResourceAdapter ra;
+
+ private Class beanClass;
+
+ public Class getBeanClass() {
+ return beanClass;
+ }
+
+ public void setBeanClass(final Class beanClass) {
+ this.beanClass = beanClass;
+ }
+
+ public void validate() throws InvalidPropertyException {
+ log.finest("validate()");
+
+ }
+
+ public ResourceAdapter getResourceAdapter() {
+ log.finest("getResourceAdapter()");
+ return ra;
+ }
+
+ public void setResourceAdapter(ResourceAdapter ra) {
+ log.finest("setResourceAdapter()");
+ this.ra = ra;
+ }
+
+
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-rar/pom.xml b/chatterbox-xmpp/chatterbox-xmpp-rar/pom.xml
new file mode 100755
index 0000000..1d6820f
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-rar/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-xmpp-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-xmpp-rar</artifactId>
+ <packaging>rar</packaging>
+ <name>Chatterbox :: XMPP :: Resource Adapter</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-xmpp-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/chatterbox-xmpp/chatterbox-xmpp-rar/src/main/rar/META-INF/LICENSE b/chatterbox-xmpp/chatterbox-xmpp-rar/src/main/rar/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-rar/src/main/rar/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-xmpp/chatterbox-xmpp-rar/src/main/rar/META-INF/ra.xml b/chatterbox-xmpp/chatterbox-xmpp-rar/src/main/rar/META-INF/ra.xml
new file mode 100755
index 0000000..5489152
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-rar/src/main/rar/META-INF/ra.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<connector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
+ http://java.sun.com/xml/ns/j2ee/connector_1_6.xsd"
+ version="1.6">
+
+ <display-name>XMPPConnector</display-name>
+ <vendor-name>Apache Software Foundation</vendor-name>
+ <resourceadapter-version>1.0</resourceadapter-version>
+ <license>
+ <license-required>false</license-required>
+ </license>
+ <resourceadapter>
+ <resourceadapter-class>org.apache.tomee.chatterbox.xmpp.impl.XMPPResourceAdapter</resourceadapter-class>
+ <config-property>
+ <config-property-name>host</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+ <config-property-value>localhost</config-property-value>
+ </config-property>
+ <config-property>
+ <config-property-name>port</config-property-name>
+ <config-property-type>java.lang.Integer</config-property-type>
+ <config-property-value>5222</config-property-value>
+ </config-property>
+ <config-property>
+ <config-property-name>password</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+ </config-property>
+ <config-property>
+ <config-property-name>username</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+ </config-property>
+ <outbound-resourceadapter>
+ <connection-definition>
+ <managedconnectionfactory-class>org.apache.tomee.chatterbox.xmpp.impl.XMPPManagedConnectionFactory
+ </managedconnectionfactory-class>
+ <connectionfactory-interface>XMPPConnectionFactory
+ </connectionfactory-interface>
+ <connectionfactory-impl-class>org.apache.tomee.chatterbox.xmpp.impl.XMPPConnectionFactoryImpl
+ </connectionfactory-impl-class>
+ <connection-interface>XMPPConnection</connection-interface>
+ <connection-impl-class>XMPPMessageListener</connection-impl-class>
+ </connection-definition>
+ <transaction-support>NoTransaction</transaction-support>
+ <reauthentication-support>false</reauthentication-support>
+ </outbound-resourceadapter>
+ <inbound-resourceadapter>
+ <messageadapter>
+ <messagelistener>
+ <messagelistener-type>XMPPMessageListener</messagelistener-type>
+ <activationspec>
+ <activationspec-class>org.apache.tomee.chatterbox.xmpp.impl.inflow.XMPPActivationSpec</activationspec-class>
+ </activationspec>
+ </messagelistener>
+ </messageadapter>
+ </inbound-resourceadapter>
+ </resourceadapter>
+</connector>
\ No newline at end of file
diff --git a/chatterbox-xmpp/chatterbox-xmpp-sample-war/pom.xml b/chatterbox-xmpp/chatterbox-xmpp-sample-war/pom.xml
new file mode 100644
index 0000000..ad4300a
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-sample-war/pom.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-xmpp-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-xmpp-sample-war</artifactId>
+ <packaging>war</packaging>
+ <name>Chatterbox :: XMPP :: Sample WAR</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-xmpp-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>chatterbox-xmpp-impl</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>apache-tomee</artifactId>
+ <version>${version.tomee}</version>
+ <classifier>plus</classifier>
+ <type>zip</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.openejb.maven</groupId>
+ <artifactId>tomee-maven-plugin</artifactId>
+ <version>${version.tomee}</version>
+ <configuration>
+ <tomeeVersion>${version.tomee}</tomeeVersion>
+ <tomeeClassifier>plus</tomeeClassifier>
+ <libs>
+ <lib>org.apache.tomee.chatterbox:chatterbox-xmpp-api:${project.version}:jar</lib>
+ </libs>
+ <apps>
+ <app>org.apache.tomee.chatterbox:chatterbox-xmpp-rar:${project.version}:rar</app>
+ </apps>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/java/org/superbiz/ChatBean.java b/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/java/org/superbiz/ChatBean.java
new file mode 100644
index 0000000..8128e4f
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/java/org/superbiz/ChatBean.java
@@ -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.
+ */
+package org.superbiz;
+
+import org.apache.tomee.chatterbox.xmpp.api.XMPPConnection;
+import org.apache.tomee.chatterbox.xmpp.api.XMPPConnectionFactory;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.MessageText;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.MessageTextParam;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.SenderParam;
+import org.apache.tomee.chatterbox.xmpp.api.inflow.XMPPMessageListener;
+
+import javax.annotation.Resource;
+import javax.ejb.MessageDriven;
+
+@MessageDriven(name = "Chat")
+public class ChatBean implements XMPPMessageListener {
+
+ @Resource
+ private XMPPConnectionFactory cf;
+
+ @MessageText("echo {message:.*$}")
+ public void echo(@SenderParam final String sender, @MessageTextParam("message") final String message) throws Exception {
+ final XMPPConnection connection = cf.getConnection();
+ connection.sendMessage(sender, message);
+ connection.close();
+ }
+
+ @MessageText("help")
+ public void help(@SenderParam final String sender) throws Exception {
+ final String message = "Commands available\n" +
+ "help - Displays this message\n" +
+ "echo <text> - Echos the text\n" +
+ "my name is <name> - greets the sender";
+
+ final XMPPConnection connection = cf.getConnection();
+ connection.sendMessage(sender, message);
+ connection.close();
+ }
+
+ @MessageText("my name is {name}")
+ public void greet(@SenderParam final String sender, @MessageTextParam("name") final String name) throws Exception {
+ final String message = "Hello " + name + ", it is very nice to meet you";
+
+ final XMPPConnection connection = cf.getConnection();
+ connection.sendMessage(sender, message);
+ connection.close();
+ }
+}
diff --git a/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/LICENSE b/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/NOTICE b/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..f2131a7
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,7 @@
+Sample Connector :: Sample WAR
+Copyright 2017-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+
diff --git a/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/ejb-jar.xml b/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/ejb-jar.xml
new file mode 100644
index 0000000..8da6664
--- /dev/null
+++ b/chatterbox-xmpp/chatterbox-xmpp-sample-war/src/main/resources/META-INF/ejb-jar.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
+ version="3.1">
+ <display-name>telnet-connector-sample-ejb</display-name>
+</ejb-jar>
diff --git a/chatterbox-xmpp/pom.xml b/chatterbox-xmpp/pom.xml
new file mode 100755
index 0000000..11adfd5
--- /dev/null
+++ b/chatterbox-xmpp/pom.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>chatterbox-xmpp-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>0.3-SNAPSHOT</version>
+ <name>Chatterbox :: XMPP</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <version.arquillian>1.1.1.Final</version.arquillian>
+ <version.tomee>1.7.2</version.tomee>
+ <version.openejb>4.7.2</version.openejb>
+ <version.crest>0.3</version.crest>
+ <maven.checkstyle.plugin.version>2.16</maven.checkstyle.plugin.version>
+ <smack-core.version>4.0.6</smack-core.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ <version>7.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.igniterealtime.smack</groupId>
+ <artifactId>smack-core</artifactId>
+ <version>${smack-core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.igniterealtime.smack</groupId>
+ <artifactId>smack-tcp</artifactId>
+ <version>${smack-core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ <version>1.2.1</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <optimize>true</optimize>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <modules>
+ <module>chatterbox-xmpp-api</module>
+ <module>chatterbox-xmpp-impl</module>
+ <module>chatterbox-xmpp-rar</module>
+ <module>chatterbox-xmpp-sample-war</module>
+ </modules>
+
+</project>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..eebe1ab
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>18</version>
+ </parent>
+
+ <groupId>org.apache.tomee.chatterbox</groupId>
+ <artifactId>chatterbox-parent</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Chatterbox</name>
+
+ <licenses>
+ <license>
+ <name>Apache License, Version 2.0</name>
+ <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <scm>
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/tomee-chatterbox.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/tomee-chatterbox.git</developerConnection>
+ <url>https://git-wip-us.apache.org/repos/asf/tomee-chatterbox.git</url>
+ <tag>HEAD</tag>
+ </scm>
+
+ <organization>
+ <name>The Apache Software Foundation</name>
+ <url>http://www.apache.org/</url>
+ </organization>
+
+ <inceptionYear>2018</inceptionYear>
+
+ <developers>
+ <developer>
+ <name>Apache TomEE Community</name>
+ <url>https://tomee.apache.org</url>
+ <organization>Apache</organization>
+ </developer>
+ </developers>
+
+ <issueManagement>
+ <system>ASF JIRA</system>
+ <url>https://issues.apache.org/jira/browse/TOMEE</url>
+ </issueManagement>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <modules>
+ <module>chatterbox-imap</module>
+ <module>chatterbox-twitter</module>
+ <module>chatterbox-xmpp</module>
+ <module>chatterbox-slack</module>
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.6.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file