You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@axis.apache.org by bi...@apache.org on 2020/04/16 15:15:16 UTC
[axis-axis2-java-transports] 02/03: Tagging the transport 1.0.0
release
This is an automated email from the ASF dual-hosted git repository.
billblough pushed a commit to tag transport
in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-transports.git
commit d02b292d7689c0923c44bcdc4052f8eca7355a3b
Author: Ruwan Linton <ru...@apache.org>
AuthorDate: Fri Dec 18 12:44:39 2009 +0000
Tagging the transport 1.0.0 release
---
1.0.0/LICENSE | 203 ++++
1.0.0/NOTICE | 5 +
1.0.0/log4j.properties | 31 +
1.0.0/modules/all/pom.xml | 216 ++++
1.0.0/modules/all/readMe.txt | 4 +
1.0.0/modules/all/src/main/assembly/src.xml | 54 +
1.0.0/modules/base/pom.xml | 167 +++
.../org/apache/axis2/format/BinaryBuilder.java | 78 ++
.../org/apache/axis2/format/BinaryFormatter.java | 96 ++
.../axis2/format/DataSourceMessageBuilder.java | 77 ++
.../org/apache/axis2/format/ElementHelper.java | 111 ++
.../org/apache/axis2/format/ManagedDataSource.java | 36 +
.../axis2/format/ManagedDataSourceFactory.java | 131 +++
.../apache/axis2/format/MessageFormatterEx.java | 44 +
.../axis2/format/MessageFormatterExAdapter.java | 83 ++
.../org/apache/axis2/format/PlainTextBuilder.java | 114 ++
.../apache/axis2/format/PlainTextFormatter.java | 98 ++
.../axis2/format/TextFromElementDataSource.java | 65 ++
.../apache/axis2/format/TextFromElementReader.java | 160 +++
.../apache/axis2/format/TextMessageBuilder.java | 48 +
.../axis2/format/TextMessageBuilderAdapter.java | 78 ++
.../WrappedTextNodeOMDataSourceFromDataSource.java | 114 ++
.../WrappedTextNodeOMDataSourceFromReader.java | 99 ++
.../axis2/format/WrappedTextNodeStreamReader.java | 437 +++++++
.../transport/base/AbstractPollTableEntry.java | 116 ++
.../base/AbstractPollingTransportListener.java | 169 +++
.../transport/base/AbstractTransportListener.java | 563 +++++++++
.../base/AbstractTransportListenerEx.java | 137 +++
.../transport/base/AbstractTransportSender.java | 417 +++++++
.../apache/axis2/transport/base/BaseConstants.java | 135 +++
.../transport/base/BaseTransportException.java | 35 +
.../org/apache/axis2/transport/base/BaseUtils.java | 276 +++++
.../axis2/transport/base/ManagementSupport.java | 50 +
.../base/MessageLevelMetricsCollector.java | 49 +
.../axis2/transport/base/MetricsCollector.java | 315 +++++
.../apache/axis2/transport/base/ParamUtils.java | 107 ++
.../axis2/transport/base/ProtocolEndpoint.java | 116 ++
.../axis2/transport/base/SynchronousCallback.java | 109 ++
.../transport/base/TransportConfiguration.java | 146 +++
.../base/TransportListenerEndpointView.java | 61 +
.../base/TransportListenerEndpointViewMBean.java | 23 +
.../transport/base/TransportMBeanSupport.java | 115 ++
.../apache/axis2/transport/base/TransportView.java | 264 +++++
.../axis2/transport/base/TransportViewMBean.java | 54 +
.../AbstractDatagramTransportListener.java | 102 ++
.../base/datagram/DatagramDispatcher.java | 27 +
.../base/datagram/DatagramDispatcherCallback.java | 23 +
.../transport/base/datagram/DatagramEndpoint.java | 57 +
.../transport/base/datagram/ProcessPacketTask.java | 67 ++
.../axis2/transport/base/datagram/Utils.java | 63 +
.../transport/base/datagram/package-info.java | 30 +
.../axis2/transport/base/event/TransportError.java | 46 +
.../base/event/TransportErrorListener.java | 24 +
.../transport/base/event/TransportErrorSource.java | 25 +
.../base/event/TransportErrorSourceSupport.java | 51 +
.../transport/base/streams/ReaderInputStream.java | 229 ++++
.../transport/base/streams/WriterOutputStream.java | 257 +++++
.../base/threads/NativeThreadFactory.java | 53 +
.../transport/base/threads/NativeWorkerPool.java | 78 ++
.../axis2/transport/base/threads/WorkerPool.java | 49 +
.../transport/base/threads/WorkerPoolFactory.java | 34 +
.../transport/base/tracker/AxisServiceFilter.java | 36 +
.../transport/base/tracker/AxisServiceTracker.java | 244 ++++
.../base/tracker/AxisServiceTrackerListener.java | 41 +
.../axis2/transport/base/tracker/package-info.java | 26 +
.../axis2/format/CharacterStreamComparator.java | 70 ++
.../org/apache/axis2/format/ElementHelperTest.java | 126 ++
.../axis2/format/ManagedDataSourceFactoryTest.java | 59 +
.../axis2/format/PlainTextFormatterTest.java | 81 ++
.../org/apache/axis2/format/RandomDataSource.java | 70 ++
.../axis2/format/TextFromElementReaderTest.java | 45 +
.../format/WrappedTextNodeOMDataSourceTest.java | 49 +
.../format/WrappedTextNodeStreamReaderTest.java | 153 +++
1.0.0/modules/http/pom.xml | 118 ++
.../http/HttpTransportDescriptionFactory.java | 47 +
.../axis2/transport/http/SimpleHTTPServerTest.java | 39 +
1.0.0/modules/jms/pom.xml | 204 ++++
.../axis2/transport/jms/AxisJMSException.java | 32 +
.../axis2/transport/jms/JMSConnectionFactory.java | 406 +++++++
.../transport/jms/JMSConnectionFactoryManager.java | 121 ++
.../apache/axis2/transport/jms/JMSConstants.java | 273 +++++
.../apache/axis2/transport/jms/JMSEndpoint.java | 254 ++++
.../apache/axis2/transport/jms/JMSListener.java | 212 ++++
.../axis2/transport/jms/JMSMessageReceiver.java | 214 ++++
.../axis2/transport/jms/JMSMessageSender.java | 319 +++++
.../axis2/transport/jms/JMSOutTransportInfo.java | 384 +++++++
.../org/apache/axis2/transport/jms/JMSSender.java | 490 ++++++++
.../org/apache/axis2/transport/jms/JMSUtils.java | 723 ++++++++++++
.../axis2/transport/jms/ServiceTaskManager.java | 1214 ++++++++++++++++++++
.../transport/jms/ServiceTaskManagerFactory.java | 326 ++++++
.../axis2/transport/jms/ctype/ContentTypeInfo.java | 49 +
.../axis2/transport/jms/ctype/ContentTypeRule.java | 43 +
.../jms/ctype/ContentTypeRuleFactory.java | 74 ++
.../transport/jms/ctype/ContentTypeRuleSet.java | 64 ++
.../axis2/transport/jms/ctype/DefaultRule.java | 37 +
.../axis2/transport/jms/ctype/MessageTypeRule.java | 39 +
.../axis2/transport/jms/ctype/PropertyRule.java | 39 +
.../axis2/transport/jms/ctype/package-info.java | 23 +
.../jms/iowrappers/BytesMessageDataSource.java | 74 ++
.../jms/iowrappers/BytesMessageInputStream.java | 75 ++
.../jms/iowrappers/BytesMessageOutputStream.java | 56 +
.../jms/iowrappers/JMSExceptionWrapper.java | 28 +
.../org/apache/axis2/transport/jms/package.html | 356 ++++++
.../transport/jms/ActiveMQTestEnvironment.java | 75 ++
.../axis2/transport/jms/ContentTypeMode.java | 38 +
.../axis2/transport/jms/JMSAsyncChannel.java | 32 +
.../apache/axis2/transport/jms/JMSAsyncClient.java | 35 +
.../jms/JMSAxisTestClientConfigurator.java | 42 +
.../transport/jms/JMSBytesMessageFactory.java | 47 +
.../org/apache/axis2/transport/jms/JMSChannel.java | 144 +++
.../org/apache/axis2/transport/jms/JMSClient.java | 86 ++
.../axis2/transport/jms/JMSMessageFactory.java | 32 +
.../transport/jms/JMSRequestResponseChannel.java | 88 ++
.../transport/jms/JMSRequestResponseClient.java | 72 ++
.../axis2/transport/jms/JMSTestEnvironment.java | 58 +
.../axis2/transport/jms/JMSTextMessageFactory.java | 44 +
.../jms/JMSTransportDescriptionFactory.java | 161 +++
.../axis2/transport/jms/JMSTransportTest.java | 108 ++
.../axis2/transport/jms/JNDIEnvironment.java | 45 +
.../org/apache/axis2/transport/jms/LogAspect.java | 77 ++
.../axis2/transport/jms/MockEchoEndpoint.java | 102 ++
.../axis2/transport/jms/QpidTestEnvironment.java | 77 ++
.../org/apache/axis2/transport/jms/QpidUtil.java | 50 +
.../transport/jms/ctype/ContentTypeRuleTest.java | 84 ++
.../jms/src/test/resources/META-INF/aop.xml | 27 +
.../org/apache/axis2/transport/jms/ctype/test1.xml | 9 +
.../org/apache/axis2/transport/jms/ctype/test2.xml | 9 +
1.0.0/modules/mail/pom.xml | 173 +++
.../org/apache/axis2/transport/mail/LogWriter.java | 80 ++
.../apache/axis2/transport/mail/MailConstants.java | 99 ++
.../axis2/transport/mail/MailOutTransportInfo.java | 86 ++
.../mail/MailRequestResponseTransport.java | 53 +
.../transport/mail/MailTransportListener.java | 755 ++++++++++++
.../axis2/transport/mail/MailTransportSender.java | 484 ++++++++
.../org/apache/axis2/transport/mail/MailUtils.java | 49 +
.../axis2/transport/mail/PollTableEntry.java | 328 ++++++
.../apache/axis2/transport/mail/WSMimeMessage.java | 77 ++
.../apache/axis2/transport/mail/FlatLayout.java | 32 +
.../transport/mail/GreenMailTestEnvironment.java | 146 +++
.../org/apache/axis2/transport/mail/LogAspect.java | 49 +
.../axis2/transport/mail/MailAsyncClient.java | 35 +
.../mail/MailAxisTestClientConfigurator.java | 42 +
.../apache/axis2/transport/mail/MailChannel.java | 84 ++
.../apache/axis2/transport/mail/MailClient.java | 82 ++
.../mail/MailMessageContextValidator.java | 60 +
.../transport/mail/MailRequestResponseClient.java | 131 +++
.../axis2/transport/mail/MailTestEnvironment.java | 93 ++
.../axis2/transport/mail/MailTransportTest.java | 75 ++
.../apache/axis2/transport/mail/MessageLayout.java | 30 +
.../axis2/transport/mail/MultipartLayout.java | 41 +
.../mail/ResponseListenerConfigurator.java | 47 +
.../mail/src/test/resources/META-INF/aop.xml | 27 +
1.0.0/modules/sms/conf/axis2.xml | 1094 ++++++++++++++++++
1.0.0/modules/sms/pom.xml | 226 ++++
.../services/SampleService/META-INF/MANIFEST.MF | 8 +
.../services/SampleService/META-INF/services.xml | 30 +
.../sms/DefaultSMSMessageBuilderImpl.java | 301 +++++
.../sms/DefaultSMSMessageFormatterImpl.java | 86 ++
.../sms/InvalidMessageFormatException.java | 36 +
.../apache/axis2/transport/sms/SMSImplManager.java | 75 ++
.../org/apache/axis2/transport/sms/SMSManager.java | 228 ++++
.../org/apache/axis2/transport/sms/SMSMessage.java | 127 ++
.../axis2/transport/sms/SMSMessageBuilder.java | 44 +
.../axis2/transport/sms/SMSMessageFormatter.java | 36 +
.../axis2/transport/sms/SMSMessageReciever.java | 84 ++
.../org/apache/axis2/transport/sms/SMSSender.java | 56 +
.../axis2/transport/sms/SMSTransportConstents.java | 73 ++
.../axis2/transport/sms/SMSTransportUtils.java | 72 ++
.../axis2/transport/sms/gsm/GSMDispatcher.java | 95 ++
.../axis2/transport/sms/gsm/GSMImplManager.java | 255 ++++
.../transport/sms/gsm/GSMServiceRepository.java | 87 ++
.../transport/sms/gsm/GSMTransportInDetails.java | 92 ++
.../transport/sms/gsm/GSMTransportOutDetails.java | 81 ++
.../axis2/transport/sms/smpp/SMPPDispatcher.java | 49 +
.../axis2/transport/sms/smpp/SMPPImplManager.java | 286 +++++
.../axis2/transport/sms/smpp/SMPPListener.java | 106 ++
.../axis2/transport/sms/smpp/SMPPMessage.java | 66 ++
.../transport/sms/smpp/SMPPTransportInDetails.java | 110 ++
.../sms/smpp/SMPPTransportOutDetails.java | 123 ++
.../axis2/transport/sms/smpp/SimpleSMPPServer.java | 30 +
.../axis2/transport/sms/SMSTransportTest.java | 110 ++
.../transport/sms/SimpleInOutMessageReceiver.java | 66 ++
.../axis2/transport/sms/smpp/MessageHolder.java | 51 +
.../transport/sms/smpp/SMSCMessageNotifier.java | 70 ++
.../transport/sms/smpp/SMSCMessageObserver.java | 37 +
.../axis2/transport/sms/smpp/SimpleSMSC.java | 178 +++
1.0.0/modules/tcp/conf/axis2.xml | 249 ++++
1.0.0/modules/tcp/pom.xml | 145 +++
.../org/apache/axis2/transport/tcp/TCPServer.java | 231 ++++
.../axis2/transport/tcp/TCPTransportSender.java | 133 +++
.../org/apache/axis2/transport/tcp/TCPWorker.java | 117 ++
.../test/org/apache/axis2/transport/tcp/Echo.java | 70 ++
.../axis2/transport/tcp/TCPEchoRawXMLTest.java | 234 ++++
.../transport/tcp/TCPTwoChannelEchoRawXMLTest.java | 144 +++
.../apache/axis2/transport/tcp/UtilsTCPServer.java | 116 ++
1.0.0/modules/testkit/pom.xml | 220 ++++
.../axis2/transport/AbstractTransportTest.java | 111 ++
.../axis2/transport/CustomAxisConfigurator.java | 61 +
.../main/java/org/apache/axis2/transport/Echo.java | 67 ++
.../axis2/transport/UtilsTransportServer.java | 126 ++
.../apache/axis2/transport/testkit/Adapter.java | 24 +
.../axis2/transport/testkit/AdapterUtils.java | 43 +
.../axis2/transport/testkit/ManagedTestSuite.java | 131 +++
.../testkit/MessageExchangeValidator.java | 25 +
.../axis2/transport/testkit/MessageTestData.java | 47 +
.../testkit/TransportTestSuiteBuilder.java | 278 +++++
.../testkit/axis2/AxisServiceConfigurator.java | 37 +
.../axis2/transport/testkit/axis2/LogAspect.java | 98 ++
.../testkit/axis2/MessageContextValidator.java | 26 +
.../axis2/SimpleTransportDescriptionFactory.java | 51 +
.../testkit/axis2/TransportDescriptionFactory.java | 46 +
.../testkit/axis2/client/AxisAsyncTestClient.java | 43 +
.../client/AxisRequestResponseTestClient.java | 54 +
.../testkit/axis2/client/AxisTestClient.java | 157 +++
.../axis2/client/AxisTestClientConfigurator.java | 27 +
.../axis2/client/AxisTestClientContext.java | 112 ++
.../client/AxisTestClientContextConfigurator.java | 40 +
.../testkit/axis2/endpoint/AxisAsyncEndpoint.java | 97 ++
.../testkit/axis2/endpoint/AxisEchoEndpoint.java | 59 +
.../testkit/axis2/endpoint/AxisTestEndpoint.java | 151 +++
.../axis2/endpoint/AxisTestEndpointContext.java | 102 ++
.../AxisTestEndpointContextConfigurator.java | 33 +
.../endpoint/ContentTypeServiceConfigurator.java | 46 +
.../util/MessageLevelMetricsCollectorImpl.java | 84 ++
.../transport/testkit/channel/AsyncChannel.java | 23 +
.../axis2/transport/testkit/channel/Channel.java | 28 +
.../testkit/channel/RequestResponseChannel.java | 23 +
.../transport/testkit/client/AsyncTestClient.java | 26 +
.../testkit/client/AsyncTestClientAdapter.java | 47 +
.../transport/testkit/client/ClientOptions.java | 65 ++
.../testkit/client/RequestResponseTestClient.java | 28 +
.../client/RequestResponseTestClientAdapter.java | 55 +
.../axis2/transport/testkit/client/TestClient.java | 29 +
.../axis2/transport/testkit/doclet/Dependency.java | 48 +
.../axis2/transport/testkit/doclet/Resource.java | 50 +
.../transport/testkit/doclet/ResourceInfo.java | 59 +
.../testkit/doclet/ResourceInfoDoclet.java | 144 +++
.../testkit/doclet/TestkitJavadocDoclet.java | 112 ++
.../transport/testkit/endpoint/AsyncEndpoint.java | 62 +
.../testkit/endpoint/AsyncEndpointAdapter.java | 55 +
.../testkit/endpoint/EndpointErrorListener.java | 24 +
.../testkit/endpoint/InOnlyEndpointSupport.java | 69 ++
.../transport/testkit/endpoint/InOutEndpoint.java | 33 +
.../testkit/endpoint/InOutEndpointSupport.java | 41 +
.../transport/testkit/endpoint/TestEndpoint.java | 26 +
.../transport/testkit/endpoint/package-info.java | 41 +
.../transport/testkit/filter/AndExpression.java | 42 +
.../testkit/filter/EqualityExpression.java | 39 +
.../transport/testkit/filter/FilterExpression.java | 35 +
.../testkit/filter/FilterExpressionParser.java | 75 ++
.../transport/testkit/filter/NotExpression.java | 37 +
.../transport/testkit/filter/OrExpression.java | 42 +
.../testkit/filter/PresenceExpression.java | 37 +
.../transport/testkit/filter/package-info.java | 30 +
.../axis2/transport/testkit/http/HttpChannel.java | 56 +
.../http/HttpTransportTestSuiteBuilder.java | 86 ++
.../transport/testkit/http/JavaNetClient.java | 61 +
.../transport/testkit/http/JavaNetRESTClient.java | 64 ++
.../transport/testkit/http/JettyAsyncEndpoint.java | 59 +
.../testkit/http/JettyByteArrayAsyncEndpoint.java | 75 ++
.../transport/testkit/http/JettyEchoEndpoint.java | 59 +
.../transport/testkit/http/JettyEndpoint.java | 65 ++
.../testkit/http/JettyRESTAsyncEndpoint.java | 48 +
.../axis2/transport/testkit/http/JettyServer.java | 56 +
.../transport/testkit/message/AxisMessage.java | 84 ++
.../transport/testkit/message/IncomingMessage.java | 40 +
.../transport/testkit/message/MessageDecoder.java | 169 +++
.../transport/testkit/message/MessageEncoder.java | 174 +++
.../transport/testkit/message/RESTMessage.java | 93 ++
.../transport/testkit/message/XMLMessage.java | 109 ++
.../apache/axis2/transport/testkit/name/Key.java | 31 +
.../apache/axis2/transport/testkit/name/Name.java | 33 +
.../axis2/transport/testkit/name/NameUtils.java | 95 ++
.../apache/axis2/transport/testkit/name/Named.java | 30 +
.../axis2/transport/testkit/package-info.java | 293 +++++
.../transport/testkit/tests/ManagedTestCase.java | 128 +++
.../transport/testkit/tests/MessageTestCase.java | 69 ++
.../axis2/transport/testkit/tests/Setup.java | 33 +
.../axis2/transport/testkit/tests/TearDown.java | 33 +
.../transport/testkit/tests/TestResource.java | 229 ++++
.../transport/testkit/tests/TestResourceSet.java | 177 +++
.../testkit/tests/TestResourceSetTransition.java | 82 ++
.../axis2/transport/testkit/tests/Transient.java | 33 +
.../testkit/tests/async/AsyncMessageTestCase.java | 61 +
.../testkit/tests/async/BinaryTestCase.java | 51 +
.../tests/async/LargeSOAPAsyncMessageTestCase.java | 69 ++
.../testkit/tests/async/RESTTestCase.java | 55 +
.../transport/testkit/tests/async/SwATestCase.java | 78 ++
.../testkit/tests/async/TextPlainTestCase.java | 57 +
.../tests/async/XMLAsyncMessageTestCase.java | 72 ++
.../echo/InterruptingEndpointErrorListener.java | 40 +
.../tests/echo/RequestResponseMessageTestCase.java | 64 ++
.../echo/XMLRequestResponseMessageTestCase.java | 72 ++
.../testkit/tests/misc/MinConcurrencyTest.java | 171 +++
.../transport/testkit/util/ContentTypeUtil.java | 54 +
.../util/LifecycleFixTransportListenerProxy.java | 75 ++
.../axis2/transport/testkit/util/LogManager.java | 79 ++
.../transport/testkit/util/PortAllocator.java | 59 +
.../axis2/transport/testkit/util/ServerUtil.java | 63 +
.../transport/testkit/util/tcpmon/Acceptor.java | 62 +
.../axis2/transport/testkit/util/tcpmon/Relay.java | 73 ++
.../transport/testkit/util/tcpmon/Tunnel.java | 51 +
.../testkit/src/main/resources/META-INF/aop.xml | 24 +
.../resources/org/apache/axis2/transport/axis2.xml | 244 ++++
.../org/apache/axis2/transport/repo/__root__ | 0
.../axis2/transport/repo/modules/modules.list | 1 +
1.0.0/modules/udp/pom.xml | 87 ++
.../org/apache/axis2/transport/udp/Endpoint.java | 68 ++
.../apache/axis2/transport/udp/IODispatcher.java | 261 +++++
.../apache/axis2/transport/udp/UDPConstants.java | 32 +
.../apache/axis2/transport/udp/UDPListener.java | 57 +
.../axis2/transport/udp/UDPOutTransportInfo.java | 76 ++
.../org/apache/axis2/transport/udp/UDPSender.java | 73 ++
.../apache/axis2/transport/udp/package-info.java | 101 ++
.../org/apache/axis2/transport/udp/UDPTest.java | 79 ++
.../apache/axis2/transport/udp/UtilsUDPServer.java | 44 +
1.0.0/modules/xmpp/pom.xml | 118 ++
.../apache/axis2/transport/xmpp/XMPPListener.java | 199 ++++
.../apache/axis2/transport/xmpp/XMPPSender.java | 485 ++++++++
.../xmpp/util/XMPPClientSidePacketListener.java | 63 +
.../transport/xmpp/util/XMPPConnectionFactory.java | 169 +++
.../axis2/transport/xmpp/util/XMPPConstants.java | 53 +
.../transport/xmpp/util/XMPPOutTransportInfo.java | 84 ++
.../transport/xmpp/util/XMPPPacketListener.java | 335 ++++++
.../transport/xmpp/util/XMPPServerCredentials.java | 84 ++
.../axis2/transport/xmpp/util/XMPPUtils.java | 79 ++
1.0.0/pom.xml | 503 ++++++++
1.0.0/src/site/apt/jms.apt | 343 ++++++
1.0.0/src/site/apt/tcp-transport.apt | 118 ++
1.0.0/src/site/resources/css/site.css | 165 +++
1.0.0/src/site/resources/download.cgi | 6 +
1.0.0/src/site/resources/images/asfLogo.jpg | Bin 0 -> 27325 bytes
.../site/resources/images/axis2TransportsLogo.gif | Bin 0 -> 5984 bytes
1.0.0/src/site/resources/images/headerBg.jpg | Bin 0 -> 405 bytes
1.0.0/src/site/resources/images/menuBg.jpg | Bin 0 -> 598 bytes
1.0.0/src/site/resources/images/spacer.gif | Bin 0 -> 43 bytes
1.0.0/src/site/site.xml | 78 ++
1.0.0/src/site/xdoc/building.xml | 98 ++
1.0.0/src/site/xdoc/docs_index.xml | 50 +
1.0.0/src/site/xdoc/download.xml | 385 +++++++
1.0.0/src/site/xdoc/download_index.xml | 52 +
1.0.0/src/site/xdoc/index.xml | 55 +
1.0.0/src/site/xdoc/mail.xml | 200 ++++
1.0.0/src/site/xdoc/sms.xml | 276 +++++
1.0.0/src/site/xdoc/xmpp.xml | 26 +
345 files changed, 37823 insertions(+)
diff --git a/1.0.0/LICENSE b/1.0.0/LICENSE
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/1.0.0/LICENSE
@@ -0,0 +1,203 @@
+
+ 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/1.0.0/NOTICE b/1.0.0/NOTICE
new file mode 100644
index 0000000..090d4e8
--- /dev/null
+++ b/1.0.0/NOTICE
@@ -0,0 +1,5 @@
+ Apache Axis2 Transports
+ Copyright 2009 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/1.0.0/log4j.properties b/1.0.0/log4j.properties
new file mode 100644
index 0000000..f63c33c
--- /dev/null
+++ b/1.0.0/log4j.properties
@@ -0,0 +1,31 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# log4j configuration file used by unit tests
+
+log4j.rootCategory=DEBUG, CONSOLE
+#log4j.rootCategory=WARN, CONSOLE
+
+log4j.category.org.apache.axis2.transport.jms=TRACE
+
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.threshold=ERROR
+#log4j.appender.CONSOLE.threshold=TRACE
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%5p [%t] %c{1} %m%n
diff --git a/1.0.0/modules/all/pom.xml b/1.0.0/modules/all/pom.xml
new file mode 100644
index 0000000..ff122a2
--- /dev/null
+++ b/1.0.0/modules/all/pom.xml
@@ -0,0 +1,216 @@
+<?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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transports</artifactId>
+ <version>1.0.0</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-all</artifactId>
+ <version>1.0.0</version>
+ <packaging>bundle</packaging>
+ <description>Axis2 Transport</description>
+ <name>Apache Axis2 - Transport - All</name>
+ <profiles>
+ <profile>
+ <id>release</id>
+ <activation>
+ <property>
+ <name>release</name>
+ <value/>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.apache.org/repos/asf/webservices/commons/tags/transport</tagBase>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>cobertura</id>
+ <dependencies>
+ <dependency>
+ <groupId>net.sourceforge.cobertura</groupId>
+ <artifactId>cobertura</artifactId>
+ <version>1.9</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <tasks>
+ <taskdef classpathref="maven.runtime.classpath" resource="tasks.properties"/>
+ <mkdir dir="target/classes"/>
+ <cobertura-instrument datafile="../../target/cobertura.ser">
+ <fileset dir="target/classes">
+ <exclude name="org/apache/axis2/transport/testkit/**/*.class"/>
+ </fileset>
+ </cobertura-instrument>
+ </tasks>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-base</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-jms</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-mail</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-tcp</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-sms</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-xmpp</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-udp</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>../..</directory>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-2</version>
+ <executions>
+ <execution>
+ <id>distribution-package</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/src.xml</descriptor>
+ </descriptors>
+ <finalName>axis2-transports-${pom.version}</finalName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.4.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Version>1.0</Bundle-Version>
+ <Bundle-Name>${pom.artifactId}</Bundle-Name>
+ <Bundle-Vendor>Apache Software Foundation</Bundle-Vendor>
+ <Bundle-Description>${pom.description}</Bundle-Description>
+ <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+ <Export-Package>
+ org.apache.axis2.transport.base.*;-split-package:=merge-last,
+ org.apache.axis2.transport.jms.*;-split-package:=merge-last,
+ org.apache.axis2.transport.mail.*;-split-package:=merge-last,
+ org.apache.axis2.transport.tcp.*;-split-package:=merge-last,
+ org.apache.axis2.transport.sms.*;-split-package:=merge-last,
+ org.apache.axis2.transport.xmpp.*;-split-package:=merge-last,
+ org.apache.axis2.transport.udp.*;-split-package:=merge-last,
+ org.apache.axis2.format.*;-split-package:=merge-last,
+ </Export-Package>
+ <Import-Package>
+ !javax.xml.namespace,
+ javax.xml.namespace; version=0.0.0,
+ *; resolution:=optional
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1.1</version>
+ <configuration>
+ <attach>false</attach>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/1.0.0/modules/all/readMe.txt b/1.0.0/modules/all/readMe.txt
new file mode 100644
index 0000000..c2fc700
--- /dev/null
+++ b/1.0.0/modules/all/readMe.txt
@@ -0,0 +1,4 @@
+Why parent module
+ The only reason behind having this module to do a small trick to build
+ a single jar from all the sub-modules. If you know a way to fix this
+in a better manner , then please remove the parent module.
\ No newline at end of file
diff --git a/1.0.0/modules/all/src/main/assembly/src.xml b/1.0.0/modules/all/src/main/assembly/src.xml
new file mode 100644
index 0000000..73a2573
--- /dev/null
+++ b/1.0.0/modules/all/src/main/assembly/src.xml
@@ -0,0 +1,54 @@
+<?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.
+ -->
+<assembly>
+ <!-- id typically identifies the "type" (src vs bin etc) of the assembly -->
+ <id>src</id>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <fileSets>
+ <fileSet>
+ <directory>../..</directory>
+ <outputDirectory>axis2-transports-${pom.version}-src</outputDirectory>
+ <includes>
+ <include>NOTICE</include>
+ <include>LICENSE</include>
+ <include>modules/**/*</include>
+ <include>**/pom.xml</include>
+ <include>src/**/*</include>
+ </includes>
+ <excludes>
+ <exclude>**/target</exclude>
+ <exclude>**/target/**/*</exclude>
+ <exclude>**/build</exclude>
+ <exclude>**/build/**/*</exclude>
+ <exclude>**/.settings</exclude>
+ <exclude>**/.classpath</exclude>
+ <exclude>**/.project</exclude>
+ <exclude>**/.wtpmodules</exclude>
+ <exclude>**/*.iml</exclude>
+ <exclude>**/.settings</exclude>
+ <exclude>**/.settings/**/*</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/1.0.0/modules/base/pom.xml b/1.0.0/modules/base/pom.xml
new file mode 100644
index 0000000..ca8d967
--- /dev/null
+++ b/1.0.0/modules/base/pom.xml
@@ -0,0 +1,167 @@
+<?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="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transports</artifactId>
+ <version>1.0.0</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-base</artifactId>
+ <name>Apache Axis2 - Transport - Base</name>
+ <description>Apache Axis2 - Base Transport</description>
+ <packaging>bundle</packaging>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>../..</directory>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.4.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Version>1.0</Bundle-Version>
+ <Bundle-Name>${pom.artifactId}</Bundle-Name>
+ <Bundle-Vendor>Apache Software Foundation</Bundle-Vendor>
+ <Bundle-Description>${pom.description}</Bundle-Description>
+ <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+ <Export-Package>
+ org.apache.axis2.transport.base.*;-split-package:=merge-last,
+ org.apache.axis2.format.*;-split-package:=merge-last,
+ </Export-Package>
+ <Import-Package>
+ !javax.xml.namespace,
+ javax.xml.namespace; version=0.0.0,
+ *;resolution:=optional,
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>axiom-api</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-javamail_1.4_spec</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-activation_1.1_spec</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>axiom-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>axiom-dom</artifactId>
+ </dependency>
+ <!-- Axis2 -->
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-kernel</artifactId>
+ <version>${axis2.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore-niossl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-javamail_1.4_spec</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-activation_1.1_spec</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>logkit</groupId>
+ <artifactId>logkit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>avalon-framework</groupId>
+ <artifactId>avalon-framework</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ <version>1.2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/BinaryBuilder.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/BinaryBuilder.java
new file mode 100644
index 0000000..cd5c3e5
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/BinaryBuilder.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.xml.namespace.QName;
+
+import org.apache.axiom.attachments.ByteArrayDataSource;
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.Parameter;
+import org.apache.commons.io.IOUtils;
+import org.apache.axis2.transport.base.BaseConstants;
+import org.apache.axis2.transport.base.BaseUtils;
+
+/**
+ * Message builder for binary payloads.
+ * <p>
+ * This builder processes the input message as binary and wraps
+ * the data in a wrapper element. The name of the wrapper element can
+ * be configured as a service parameter (see {@link BaseConstants#WRAPPER_PARAM}).
+ * It defaults to {@link BaseConstants#DEFAULT_BINARY_WRAPPER}.
+ */
+public class BinaryBuilder implements DataSourceMessageBuilder {
+ public OMElement processDocument(DataSource dataSource,
+ String contentType,
+ MessageContext msgContext) throws AxisFault {
+ QName wrapperQName = BaseConstants.DEFAULT_BINARY_WRAPPER;
+ if (msgContext.getAxisService() != null) {
+ Parameter wrapperParam = msgContext.getAxisService().getParameter(BaseConstants.WRAPPER_PARAM);
+ if (wrapperParam != null) {
+ wrapperQName = BaseUtils.getQNameFromString(wrapperParam.getValue());
+ }
+ }
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ OMElement wrapper = factory.createOMElement(wrapperQName, null);
+ DataHandler dataHandler = new DataHandler(dataSource);
+ wrapper.addChild(factory.createOMText(dataHandler, true));
+ msgContext.setDoingMTOM(true);
+ return wrapper;
+ }
+
+ public OMElement processDocument(InputStream inputStream,
+ String contentType,
+ MessageContext msgContext) throws AxisFault {
+ // TODO: this could be further optimized by deferring the read operation
+ byte[] msgBytes;
+ try {
+ msgBytes = IOUtils.toByteArray(inputStream);
+ } catch (IOException ex) {
+ throw new AxisFault("Unable to read message payload", ex);
+ }
+ return processDocument(new ByteArrayDataSource(msgBytes), contentType, msgContext);
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/BinaryFormatter.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/BinaryFormatter.java
new file mode 100644
index 0000000..406a4b4
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/BinaryFormatter.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.OMText;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.transport.http.util.URLTemplatingUtil;
+import org.apache.axis2.transport.base.BaseConstants;
+
+public class BinaryFormatter implements MessageFormatterEx {
+ public byte[] getBytes(MessageContext messageContext, OMOutputFormat format) throws AxisFault {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ writeTo(messageContext, format, baos, true);
+ return baos.toByteArray();
+ }
+
+ private DataHandler getDataHandler(MessageContext messageContext) {
+ OMElement firstChild = messageContext.getEnvelope().getBody().getFirstElement();
+ if (BaseConstants.DEFAULT_BINARY_WRAPPER.equals(firstChild.getQName())) {
+ OMNode omNode = firstChild.getFirstOMChild();
+ if (omNode != null && omNode instanceof OMText) {
+ Object dh = ((OMText)omNode).getDataHandler();
+ if (dh != null && dh instanceof DataHandler) {
+ return (DataHandler)dh;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void writeTo(MessageContext messageContext, OMOutputFormat format,
+ OutputStream outputStream, boolean preserve) throws AxisFault {
+ DataHandler dh = getDataHandler(messageContext);
+ if (dh != null) {
+ try {
+ ((DataHandler)dh).writeTo(outputStream);
+ } catch (IOException e) {
+ throw new AxisFault("Error serializing binary content of element : " +
+ BaseConstants.DEFAULT_BINARY_WRAPPER, e);
+ }
+ }
+ }
+
+ public String getContentType(MessageContext messageContext,
+ OMOutputFormat format, String soapAction) {
+ DataHandler dh = getDataHandler(messageContext);
+ if (dh != null) {
+ return dh.getContentType();
+ } else {
+ return null;
+ }
+ }
+
+ public URL getTargetAddress(MessageContext messageContext,
+ OMOutputFormat format, URL targetURL) throws AxisFault {
+ return URLTemplatingUtil.getTemplatedURL(targetURL, messageContext, false);
+ }
+
+ public String formatSOAPAction(MessageContext messageContext,
+ OMOutputFormat format, String soapAction) {
+ return null;
+ }
+
+ public DataSource getDataSource(MessageContext messageContext,
+ OMOutputFormat format, String soapAction) throws AxisFault {
+ return getDataHandler(messageContext).getDataSource();
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/DataSourceMessageBuilder.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/DataSourceMessageBuilder.java
new file mode 100644
index 0000000..ddbf69e
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/DataSourceMessageBuilder.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import javax.activation.DataSource;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.builder.Builder;
+import org.apache.axis2.context.MessageContext;
+
+/**
+ * Message builder able to build messages from {@link DataSource} objects.
+ * This interface can be optionally implemented by {@link Builder}
+ * implementations that support building messages from {@link DataSource} objects.
+ * Since by definition the data from a {@link DataSource} can be read multiple
+ * times, this interface can be used by message builders to avoid storing the
+ * message content in memory.
+ * <p>
+ * If a message builder implements this interface and the transport is able to
+ * provide the message payload as a data source, then the method defined by this
+ * interface should be preferred over the method defined by {@link Builder}.
+ * <p>
+ * Implementing this interface helps optimizing message processing with transports
+ * that use messaging providers that store messages in memory or on the file system.
+ * Examples are JMS and VFS.
+ * <p>
+ * The builder will typically expose the data source directly or indirectly through
+ * the returned {@link OMElement}, e.g. by adding to the tree an {@link org.apache.axiom.om.OMText}
+ * or {@link org.apache.axiom.om.OMDataSource} node referencing the data source.
+ * This means that the builder will not be able to guarantee that all streams requested
+ * from the data source are properly closed. Note that code accessing the returned
+ * {@link OMElement} can't be expected to take care of this since in many cases the fact
+ * that a data source is being used is completely transparent to that code.
+ * It is therefore the responsibility of the transport to make sure that all resources linked to
+ * the data source itself as well as any open stream requested from that data source are properly
+ * released after the message has been processed. Depending on the type of transport, there are
+ * three possible cases:
+ * <ol>
+ * <li>All resources allocated to the data source or streams requested from it are
+ * memory based. In that case the garbage collector will take care of freeing
+ * these resources and the transport should simply pass the data source object
+ * to the builder.</li>
+ * <li>There are operation system resources linked to the data source and open
+ * streams will become invalid when these resources are freed, i.e.
+ * it is not required that all streams be closed explicitly.
+ * In this case the transport only needs to take care to properly dispose of
+ * the data source after the message has been processed by the Axis2 engine.</li>
+ * <li>Requesting a stream from the data source allocates operation system resources
+ * (e.g. a network connection) that remain linked to the stream, i.e. all streams requested
+ * from the data source must be closed properly. In that case the transport should use
+ * {@link ManagedDataSourceFactory#create(DataSource)} to wrap the original data source
+ * before passing it to the builder. After the message has been processed it should
+ * then call {@link ManagedDataSource#destroy()} on the wrapper to close all remaining
+ * open streams.</li>
+ * </ol>
+ */
+public interface DataSourceMessageBuilder extends Builder {
+ public OMElement processDocument(DataSource dataSource, String contentType,
+ MessageContext messageContext) throws AxisFault;
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ElementHelper.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ElementHelper.java
new file mode 100644
index 0000000..c2f9c75
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ElementHelper.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMSourcedElement;
+import org.apache.axiom.om.OMText;
+
+/**
+ * Utility class with methods to work on {@link OMElement} objects.
+ * <p>
+ * NOTICE: The code in this class will be moved to Axiom (or somewhere else). Use with care!
+ */
+public class ElementHelper {
+ private ElementHelper() {}
+
+ /**
+ * Returns a stream representing the concatenation of the text nodes that are children of a
+ * given element.
+ * The stream returned by this method produces exactly the same character sequence as the
+ * the stream created by the following expression:
+ * <pre>new StringReader(element.getText())</pre>
+ * The difference is that the stream implementation returned by this method is guaranteed
+ * to have constant memory usage and is optimized for performance.
+ *
+ * @param element the element to read the text nodes from
+ * @param cache whether to enable caching when accessing the element
+ * @return a stream representing the concatenation of the text nodes
+ *
+ * @see OMElement#getText()
+ */
+ public static Reader getTextAsStream(OMElement element, boolean cache) {
+ // If the element is not an OMSourcedElement and has not more than one child, then the most
+ // efficient way to get the Reader is to build a StringReader
+ if (!(element instanceof OMSourcedElement) && (!cache || element.isComplete())) {
+ OMNode child = element.getFirstOMChild();
+ if (child == null) {
+ return new StringReader("");
+ } else if (child.getNextOMSibling() == null) {
+ return new StringReader(child instanceof OMText ? ((OMText)child).getText() : "");
+ }
+ }
+ // In all other cases, extract the data from the XMLStreamReader
+ return new TextFromElementReader(cache ? element.getXMLStreamReader()
+ : element.getXMLStreamReaderWithoutCaching());
+ }
+
+ /**
+ * Write the content of the text nodes that are children of a given element to a
+ * {@link Writer}.
+ * If <code>cache</code> is true, this method has the same effect as the following instruction:
+ * <pre>out.write(element.getText())</pre>
+ * The difference is that this method is guaranteed to have constant memory usage and is
+ * optimized for performance.
+ *
+ * @param element the element to read the text nodes from
+ * @param out the stream to write the content to
+ * @param cache whether to enable caching when accessing the element
+ * @throws XMLStreamException if an error occurs when reading from the element
+ * @throws IOException if an error occurs when writing to the stream
+ *
+ * @see OMElement#getText()
+ */
+ public static void writeTextTo(OMElement element, Writer out, boolean cache)
+ throws XMLStreamException, IOException {
+
+ XMLStreamReader reader = cache ? element.getXMLStreamReader()
+ : element.getXMLStreamReaderWithoutCaching();
+ int depth = 0;
+ while (reader.hasNext()) {
+ switch (reader.next()) {
+ case XMLStreamReader.CHARACTERS:
+ case XMLStreamReader.CDATA:
+ if (depth == 1) {
+ out.write(reader.getText());
+ }
+ break;
+ case XMLStreamReader.START_ELEMENT:
+ depth++;
+ break;
+ case XMLStreamReader.END_ELEMENT:
+ depth--;
+ }
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ManagedDataSource.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ManagedDataSource.java
new file mode 100644
index 0000000..f72d7e9
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ManagedDataSource.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.format;
+
+import javax.activation.DataSource;
+
+/**
+ * Managed data source.
+ * This type of data source keeps track of the streams that have been
+ * requested using {@link DataSource#getInputStream()} and allows to
+ * forcibly close these streams. Any existing data source can be converted
+ * to a managed data source using {@link ManagedDataSourceFactory#create(DataSource)}.
+ */
+public interface ManagedDataSource extends DataSource {
+ /**
+ * Close all streams that have been requested from this data source
+ * and that are not yet closed.
+ */
+ void destroy();
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ManagedDataSourceFactory.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ManagedDataSourceFactory.java
new file mode 100644
index 0000000..d27024c
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/ManagedDataSourceFactory.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.activation.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Utility class to create {@link ManagedDataSource} objects.
+ */
+public class ManagedDataSourceFactory {
+ private static class ManagedInputStream extends FilterInputStream {
+ private DataSourceManager manager;
+
+ public ManagedInputStream(DataSourceManager manager, InputStream parent) {
+ super(parent);
+ this.manager = manager;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (manager != null) {
+ manager.notifyStreamClosed(this);
+ manager = null;
+ }
+ super.close();
+ }
+ }
+
+ private static class DataSourceManager implements InvocationHandler {
+ private static final Log log = LogFactory.getLog(DataSourceManager.class);
+
+ private static final Method getInputStreamMethod;
+ private static final Method destroyMethod;
+
+ static {
+ try {
+ getInputStreamMethod = DataSource.class.getMethod("getInputStream");
+ destroyMethod = ManagedDataSource.class.getMethod("destroy");
+ } catch (NoSuchMethodException ex) {
+ throw new NoSuchMethodError(ex.getMessage());
+ }
+ }
+
+ private final DataSource dataSource;
+ private final List<ManagedInputStream> openStreams = Collections.synchronizedList(
+ new LinkedList<ManagedInputStream>());
+
+ public DataSourceManager(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ public void notifyStreamClosed(ManagedInputStream managedInputStream) {
+ if (!openStreams.remove(managedInputStream)) {
+ throw new IllegalStateException();
+ }
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ try {
+ if (method.equals(getInputStreamMethod)) {
+ InputStream in = (InputStream)method.invoke(dataSource, args);
+ ManagedInputStream in2 = new ManagedInputStream(this, in);
+ openStreams.add(in2);
+ return in2;
+ } else if (method.equals(destroyMethod)) {
+ while (!openStreams.isEmpty()) {
+ try {
+ openStreams.get(0).close();
+ } catch (IOException ex) {
+ log.warn("Exception when closing open stream from managed data source", ex);
+ }
+ }
+ return null;
+ } else {
+ return method.invoke(dataSource, args);
+ }
+ } catch (InvocationTargetException ex) {
+ throw ex.getCause();
+ }
+ }
+
+ }
+
+ /**
+ * Create a {@link ManagedDataSource} proxy for an existing data source.
+ * This will create a dynamic proxy implementing the same interfaces as
+ * the original data source.
+ *
+ * @param ds the original data source
+ * @return a data source proxy implementing {@link ManagedDataSource}
+ */
+ public static ManagedDataSource create(DataSource ds) {
+ Class<?>[] orgIfaces = ds.getClass().getInterfaces();
+ Class<?>[] ifaces = new Class[orgIfaces.length+1];
+ ifaces[0] = ManagedDataSource.class;
+ System.arraycopy(orgIfaces, 0, ifaces, 1, orgIfaces.length);
+ return (ManagedDataSource)Proxy.newProxyInstance(
+ ManagedDataSourceFactory.class.getClassLoader(), ifaces,
+ new DataSourceManager(ds));
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/MessageFormatterEx.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/MessageFormatterEx.java
new file mode 100644
index 0000000..aee5acb
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/MessageFormatterEx.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.axis2.format;
+
+import javax.activation.DataSource;
+
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.transport.MessageFormatter;
+
+/**
+ * Message formatter with extended capabilities.
+ * This interface adds new methods to the {@link MessageFormatter}
+ * interface, allowing transport to optimize data transfers.
+ */
+public interface MessageFormatterEx extends MessageFormatter {
+ /**
+ * Get the formatted message as a {@link DataSource} object.
+ *
+ * @param messageContext
+ * @param format
+ * @param soapAction
+ * @return
+ * @throws AxisFault
+ */
+ DataSource getDataSource(MessageContext messageContext, OMOutputFormat format, String soapAction) throws AxisFault;
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/MessageFormatterExAdapter.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/MessageFormatterExAdapter.java
new file mode 100644
index 0000000..a802e2f
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/MessageFormatterExAdapter.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.OutputStream;
+import java.net.URL;
+
+import javax.activation.DataSource;
+
+import org.apache.axiom.attachments.ByteArrayDataSource;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.transport.MessageFormatter;
+
+/**
+ * Adapter to add the {@link MessageFormatterEx} interface to an
+ * existing {@link MessageFormatter}.
+ * It implements the {@link MessageFormatterEx#getDataSource(MessageContext, OMOutputFormat, String)} method
+ * using {@link MessageFormatter#getBytes(MessageContext, OMOutputFormat)} and
+ * {@link MessageFormatter#getContentType(MessageContext, OMOutputFormat, String)}.
+ */
+public class MessageFormatterExAdapter implements MessageFormatterEx {
+ private final MessageFormatter messageFormatter;
+
+ public MessageFormatterExAdapter(MessageFormatter messageFormatter) {
+ this.messageFormatter = messageFormatter;
+ }
+
+ public DataSource getDataSource(MessageContext messageContext,
+ OMOutputFormat format,
+ String soapAction) throws AxisFault {
+ return new ByteArrayDataSource(
+ getBytes(messageContext, format),
+ getContentType(messageContext, format, soapAction));
+ }
+
+ public String formatSOAPAction(MessageContext messageContext,
+ OMOutputFormat format,
+ String soapAction) {
+ return messageFormatter.formatSOAPAction(messageContext, format, soapAction);
+ }
+
+ public byte[] getBytes(MessageContext messageContext,
+ OMOutputFormat format) throws AxisFault {
+ return messageFormatter.getBytes(messageContext, format);
+ }
+
+ public String getContentType(MessageContext messageContext,
+ OMOutputFormat format,
+ String soapAction) {
+ return messageFormatter.getContentType(messageContext, format, soapAction);
+ }
+
+ public URL getTargetAddress(MessageContext messageContext,
+ OMOutputFormat format,
+ URL targetURL) throws AxisFault {
+ return messageFormatter.getTargetAddress(messageContext, format, targetURL);
+ }
+
+ public void writeTo(MessageContext messageContext,
+ OMOutputFormat format,
+ OutputStream outputStream,
+ boolean preserve) throws AxisFault {
+ messageFormatter.writeTo(messageContext, format, outputStream, preserve);
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/PlainTextBuilder.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/PlainTextBuilder.java
new file mode 100644
index 0000000..ee52ee0
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/PlainTextBuilder.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+
+import javax.activation.DataSource;
+import javax.xml.namespace.QName;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.impl.llom.OMSourcedElementImpl;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.builder.BuilderUtil;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.transport.base.BaseConstants;
+import org.apache.axis2.transport.base.BaseUtils;
+
+/**
+ * Message builder for plain text payloads.
+ * <p>
+ * This builder processes the input message as plain text and wraps
+ * the text in a wrapper element. The name of the wrapper element can
+ * be configured as a service parameter (see {@link BaseConstants#WRAPPER_PARAM}).
+ * It defaults to {@link BaseConstants#DEFAULT_TEXT_WRAPPER}.
+ * If the content is provided as an {@link InputStream} and the content type specifies a
+ * <tt>charset</tt> parameter (e.g. <tt>text/plain; charset=ISO-8859-15</tt>),
+ * this information is used to decode the text.
+ * If the content is provided as an {@link InputStream} but no <tt>charset</tt> parameter
+ * is specified on the content type, the default charset encoding specified by
+ * {@link MessageContext#DEFAULT_CHAR_SET_ENCODING} is used.
+ */
+public class PlainTextBuilder implements TextMessageBuilder, DataSourceMessageBuilder {
+ private static QName getWrapperQName(MessageContext msgContext) {
+ QName wrapperQName = BaseConstants.DEFAULT_TEXT_WRAPPER;
+ if (msgContext.getAxisService() != null) {
+ Parameter wrapperParam
+ = msgContext.getAxisService().getParameter(BaseConstants.WRAPPER_PARAM);
+ if (wrapperParam != null) {
+ wrapperQName = BaseUtils.getQNameFromString(wrapperParam.getValue());
+ }
+ }
+ return wrapperQName;
+ }
+
+ public OMElement processDocument(InputStream inputStream,
+ String contentType,
+ MessageContext msgContext) throws AxisFault {
+
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ String charSetEnc = BuilderUtil.getCharSetEncoding(contentType);
+ QName wrapperQName = getWrapperQName(msgContext);
+ Reader reader;
+ try {
+ reader = new InputStreamReader(inputStream, charSetEnc);
+ } catch (UnsupportedEncodingException ex) {
+ throw new AxisFault("Unsupported encoding: " + charSetEnc, ex);
+ }
+ return new OMSourcedElementImpl(wrapperQName, factory,
+ new WrappedTextNodeOMDataSourceFromReader(wrapperQName, reader));
+ }
+
+ public OMElement processDocument(Reader reader,
+ String contentType,
+ MessageContext msgContext) throws AxisFault {
+
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ QName wrapperQName = getWrapperQName(msgContext);
+ return new OMSourcedElementImpl(wrapperQName, factory,
+ new WrappedTextNodeOMDataSourceFromReader(wrapperQName, reader));
+ }
+
+ public OMElement processDocument(String content,
+ String contentType,
+ MessageContext msgContext) throws AxisFault {
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ OMElement wrapper = factory.createOMElement(getWrapperQName(msgContext), null);
+ factory.createOMText(wrapper, content);
+ return wrapper;
+ }
+
+ public OMElement processDocument(DataSource dataSource,
+ String contentType,
+ MessageContext msgContext) throws AxisFault {
+
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ Charset cs = Charset.forName(BuilderUtil.getCharSetEncoding(contentType));
+ QName wrapperQName = getWrapperQName(msgContext);
+ return new OMSourcedElementImpl(wrapperQName, factory,
+ new WrappedTextNodeOMDataSourceFromDataSource(wrapperQName, dataSource, cs));
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/PlainTextFormatter.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/PlainTextFormatter.java
new file mode 100644
index 0000000..5c29f0b
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/PlainTextFormatter.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import org.apache.axis2.transport.http.util.URLTemplatingUtil;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.AxisFault;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.transport.base.BaseConstants;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.net.URL;
+
+import javax.activation.DataSource;
+import javax.xml.stream.XMLStreamException;
+
+public class PlainTextFormatter implements MessageFormatterEx {
+
+ public byte[] getBytes(MessageContext messageContext, OMOutputFormat format) throws AxisFault {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ writeTo(messageContext, format, baos, true);
+ return baos.toByteArray();
+ }
+
+ public void writeTo(MessageContext messageContext, OMOutputFormat format, OutputStream outputStream, boolean preserve) throws AxisFault {
+ OMElement textElt = messageContext.getEnvelope().getBody().getFirstElement();
+ if (BaseConstants.DEFAULT_TEXT_WRAPPER.equals(textElt.getQName())) {
+ try {
+ Writer out = new OutputStreamWriter(outputStream, format.getCharSetEncoding());
+ ElementHelper.writeTextTo(textElt, out, preserve);
+ out.flush();
+ } catch (IOException e) {
+ throw new AxisFault("Error writing text message to stream", e);
+ } catch (XMLStreamException e) {
+ throw new AxisFault("Error extracting the text payload from the message", e);
+ }
+ }
+ }
+
+ public String getContentType(MessageContext messageContext, OMOutputFormat format, String soapAction) {
+ String encoding = format.getCharSetEncoding();
+ String contentType = "text/plain";
+
+ if (encoding != null) {
+ contentType += "; charset=" + encoding;
+ }
+
+ // if soap action is there (can be there is soap response MEP is used) add it.
+ if ((soapAction != null)
+ && !"".equals(soapAction.trim())
+ && !"\"\"".equals(soapAction.trim())) {
+ contentType = contentType + ";action=\"" + soapAction + "\";";
+ }
+
+ return contentType;
+ }
+
+ public URL getTargetAddress(MessageContext msgCtxt, OMOutputFormat format, URL targetURL) throws AxisFault {
+ // Check whether there is a template in the URL, if so we have to replace then with data
+ // values and create a new target URL.
+ targetURL = URLTemplatingUtil.getTemplatedURL(targetURL, msgCtxt, false);
+ return targetURL;
+ }
+
+ public String formatSOAPAction(MessageContext messageContext, OMOutputFormat format, String soapAction) {
+ return null;
+ }
+
+ public DataSource getDataSource(MessageContext messageContext,
+ OMOutputFormat format, String soapAction) throws AxisFault {
+ return new TextFromElementDataSource(
+ messageContext.getEnvelope().getBody().getFirstElement(),
+ format.getCharSetEncoding(),
+ getContentType(messageContext, format, soapAction));
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextFromElementDataSource.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextFromElementDataSource.java
new file mode 100644
index 0000000..b3077ac
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextFromElementDataSource.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.activation.DataSource;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.transport.base.streams.ReaderInputStream;
+
+/**
+ * Data source that represents the text of a given {@link OMElement}.
+ * <p>
+ * The expression
+ * <pre>new TextFromElementDataSource(element, charset, contentType)</pre>
+ * produces a DataSource implementation that is equivalent to
+ * <pre>new ByteArrayDataSource(element.getText().getBytes(charset), contentType)</pre>
+ * but that is more efficient.
+ */
+public class TextFromElementDataSource implements DataSource {
+ private final OMElement element;
+ private final String charset;
+ private final String contentType;
+
+ public TextFromElementDataSource(OMElement element, String charset, String contentType) {
+ this.element = element;
+ this.charset = charset;
+ this.contentType = contentType;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new ReaderInputStream(ElementHelper.getTextAsStream(element, true), charset);
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextFromElementReader.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextFromElementReader.java
new file mode 100644
index 0000000..9424308
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextFromElementReader.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.OMException;
+
+/**
+ * {@link Reader} implementation that extracts the text nodes from an element given by an
+ * {@link XMLStreamReader}. The expected input is a document with only a document
+ * element (as produced by {@link org.apache.axiom.om.OMElement.OMElement#getXMLStreamReader()}).
+ * The class will extract the text nodes that are direct children of that element, i.e. it uses
+ * the same conventions as {@link org.apache.axiom.om.OMElement.OMElement#getText()}.
+ * It will call {@link XMLStreamReader#close()} when the end of the document is reached or when
+ * {@link #close()} is called.
+ * <p>
+ * The main purpose of this class is to provide a convenient and efficient way to get the text
+ * content of an element without converting it first to a string, i.e. without using
+ * {@link org.apache.axiom.om.OMElement.OMElement#getText()}. This is important for potentially
+ * large contents, for which this class guarantees constant memory usage.
+ * <p>
+ * Note that this class should in general not be used directly. Instead,
+ * {@link ElementHelper#getTextAsStream(org.apache.axiom.om.OMElement)}
+ * should be called to get the most efficient stream implementation for a given an element.
+ * <p>
+ * NOTICE: The code in this class will be moved to Axiom (or somewhere else). Use with care!
+ */
+public class TextFromElementReader extends Reader {
+ private final XMLStreamReader stream;
+
+ /**
+ * Flag indicating that we have reached the end of the document and that the underlying
+ * parser has been closed.
+ */
+ private boolean endOfStream;
+
+ /**
+ * The current depth relative to the document element (not the document). A value greater than
+ * 0 indicates that we are inside a nested element and that we need to skip text nodes.
+ */
+ private int skipDepth;
+
+ /**
+ * The current position in the character data of the event, or -1 if all the character data
+ * has been consumed and a new event needs to be requested from the parser.
+ */
+ private int sourceStart = -1;
+
+ /**
+ * Constructor.
+ *
+ * @param stream the stream to extract the text nodes from
+ * @throws OMException if the stream doesn't start with the expected events
+ */
+ public TextFromElementReader(XMLStreamReader stream) {
+ this.stream = stream;
+ try {
+ if (stream.getEventType() != XMLStreamReader.START_DOCUMENT) {
+ throw new OMException("Expected START_DOCUMENT as first event from parser");
+ }
+ if (stream.next() != XMLStreamReader.START_ELEMENT) {
+ throw new OMException("Expected START_ELEMENT event");
+ }
+ } catch (XMLStreamException ex) {
+ throw new OMException(ex);
+ }
+ }
+
+ @Override
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ if (endOfStream) {
+ return -1;
+ }
+ int read = 0;
+ try {
+ while (true) {
+ if (sourceStart == -1) {
+ eventLoop: while (true) {
+ int type = stream.next();
+ switch (type) {
+ case XMLStreamReader.CHARACTERS:
+ case XMLStreamReader.CDATA:
+ if (skipDepth == 0) {
+ sourceStart = 0;
+ break eventLoop;
+ }
+ break;
+ case XMLStreamReader.START_ELEMENT:
+ skipDepth++;
+ break;
+ case XMLStreamReader.END_ELEMENT:
+ if (skipDepth == 0) {
+ if (stream.next() == XMLStreamReader.END_DOCUMENT) {
+ endOfStream = true;
+ stream.close();
+ return read == 0 ? -1 : read;
+ } else {
+ throw new IOException(
+ "End of document expected after element");
+ }
+ } else {
+ skipDepth--;
+ }
+ }
+ }
+ }
+ int c = stream.getTextCharacters(sourceStart, cbuf, off, len);
+ sourceStart += c;
+ off += c;
+ len -= c;
+ read += c;
+ if (len > 0) {
+ sourceStart = -1;
+ } else {
+ return read;
+ }
+ }
+ } catch (XMLStreamException ex) {
+ IOException ex2 = new IOException("Got an exception from the underlying parser " +
+ "while reading the content of an element");
+ ex2.initCause(ex);
+ throw ex2;
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (!endOfStream) {
+ try {
+ stream.close();
+ } catch (XMLStreamException ex) {
+ IOException ex2 = new IOException("Error when trying to close underlying parser");
+ ex2.initCause(ex);
+ throw ex2;
+ }
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextMessageBuilder.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextMessageBuilder.java
new file mode 100644
index 0000000..b2b0328
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextMessageBuilder.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.format;
+
+import java.io.Reader;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.builder.Builder;
+import org.apache.axis2.context.MessageContext;
+
+/**
+ * Message builder able to build messages from a character stream.
+ * This interface can be optionally implemented by {@link Builder}
+ * implementations that support building a message from a character
+ * stream.
+ * <p>
+ * The character stream can either be provided as a string or a
+ * {@link Reader} object. The caller should use a {@link Reader} object
+ * except if the content of the message is available as a string anyway.
+ * <p>
+ * This interface is currently used by the JMS transport to process
+ * {@link javax.jms.TextMessage} instances.
+ */
+public interface TextMessageBuilder extends Builder {
+ public OMElement processDocument(Reader reader, String contentType,
+ MessageContext messageContext) throws AxisFault;
+
+ public OMElement processDocument(String content, String contentType,
+ MessageContext messageContext) throws AxisFault;
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextMessageBuilderAdapter.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextMessageBuilderAdapter.java
new file mode 100644
index 0000000..7cb3cac
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/TextMessageBuilderAdapter.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+
+import javax.mail.internet.ContentType;
+import javax.mail.internet.ParseException;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.Constants;
+import org.apache.axis2.builder.Builder;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.transport.base.streams.ReaderInputStream;
+
+/**
+ * Adapter to add the {@link TextMessageBuilder} interface to an
+ * existing {@link Builder}.
+ * It implements the {@link TextMessageBuilder#processDocument(Reader, String, MessageContext)}
+ * and {@link TextMessageBuilder#processDocument(String, String, MessageContext)} by converting
+ * the character stream to a byte stream using {@link ReaderInputStream}.
+ *
+ * TODO: specifying encoding
+ */
+public class TextMessageBuilderAdapter implements TextMessageBuilder {
+ private final Builder builder;
+
+ public TextMessageBuilderAdapter(Builder builder) {
+ this.builder = builder;
+ }
+
+ public OMElement processDocument(InputStream inputStream, String contentType,
+ MessageContext messageContext) throws AxisFault {
+ return builder.processDocument(inputStream, contentType, messageContext);
+ }
+
+ public OMElement processDocument(Reader reader, String contentType,
+ MessageContext messageContext) throws AxisFault {
+ String charset;
+ try {
+ ContentType ct = new ContentType(contentType);
+ charset = ct.getParameter("charset");
+ } catch (ParseException ex) {
+ charset = null;
+ }
+ if (charset == null) {
+ charset = MessageContext.DEFAULT_CHAR_SET_ENCODING;
+ }
+ messageContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING, charset);
+ return processDocument(new ReaderInputStream(reader, charset), contentType,
+ messageContext);
+ }
+
+ public OMElement processDocument(String content, String contentType,
+ MessageContext messageContext) throws AxisFault {
+ return processDocument(new StringReader(content), contentType, messageContext);
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceFromDataSource.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceFromDataSource.java
new file mode 100644
index 0000000..85b4ece
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceFromDataSource.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
+import javax.activation.DataSource;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.axiom.om.OMDataSourceExt;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.ds.OMDataSourceExtBase;
+import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
+import org.apache.axiom.om.impl.serialize.StreamingOMSerializer;
+import org.apache.axiom.om.util.StAXUtils;
+
+/**
+ * {@link org.apache.axiom.om.OMDataSource} implementation that represents a text node wrapped
+ * inside an element. The text data is provided by a {@link DataSource} object.
+ */
+public class WrappedTextNodeOMDataSourceFromDataSource extends OMDataSourceExtBase {
+ private final QName wrapperElementName;
+ private final DataSource binaryData;
+ private final Charset charset;
+
+ public WrappedTextNodeOMDataSourceFromDataSource(QName wrapperElementName, DataSource binaryData,
+ Charset charset) {
+ this.wrapperElementName = wrapperElementName;
+ this.binaryData = binaryData;
+ this.charset = charset;
+ }
+
+ @Override
+ public void serialize(OutputStream out, OMOutputFormat format) throws XMLStreamException {
+ XMLStreamWriter writer = new MTOMXMLStreamWriter(out, format);
+ serialize(writer);
+ writer.flush();
+ }
+
+ @Override
+ public void serialize(Writer writer, OMOutputFormat format) throws XMLStreamException {
+ MTOMXMLStreamWriter xmlWriter =
+ new MTOMXMLStreamWriter(StAXUtils.createXMLStreamWriter(writer));
+ xmlWriter.setOutputFormat(format);
+ serialize(xmlWriter);
+ xmlWriter.flush();
+ }
+
+ @Override
+ public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException {
+ StreamingOMSerializer serializer = new StreamingOMSerializer();
+ serializer.serialize(getReader(), xmlWriter);
+ }
+
+ public XMLStreamReader getReader() throws XMLStreamException {
+ InputStream is;
+ try {
+ is = binaryData.getInputStream();
+ }
+ catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ return new WrappedTextNodeStreamReader(wrapperElementName, new InputStreamReader(is, charset));
+ }
+
+ public Object getObject() {
+ return binaryData;
+ }
+
+ public boolean isDestructiveRead() {
+ return false;
+ }
+
+ public boolean isDestructiveWrite() {
+ return false;
+ }
+
+ public byte[] getXMLBytes(String encoding) throws UnsupportedEncodingException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void close() {
+ }
+
+ public OMDataSourceExt copy() {
+ return new WrappedTextNodeOMDataSourceFromDataSource(wrapperElementName, binaryData, charset);
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceFromReader.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceFromReader.java
new file mode 100644
index 0000000..a42f55f
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceFromReader.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.format;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.axiom.om.OMDataSourceExt;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.ds.OMDataSourceExtBase;
+import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
+import org.apache.axiom.om.impl.serialize.StreamingOMSerializer;
+import org.apache.axiom.om.util.StAXUtils;
+
+/**
+ * {@link org.apache.axiom.om.OMDataSource} implementation that represents a text node wrapped
+ * inside an element. The text data is provided by a {@link Reader} object. Since the stream
+ * can only be read once, this data source is destructive.
+ */
+public class WrappedTextNodeOMDataSourceFromReader extends OMDataSourceExtBase {
+ private final QName wrapperElementName;
+ private final Reader reader;
+
+ public WrappedTextNodeOMDataSourceFromReader(QName wrapperElementName, Reader reader) {
+ this.wrapperElementName = wrapperElementName;
+ this.reader = reader;
+ }
+
+ @Override
+ public void serialize(Writer writer, OMOutputFormat format) throws XMLStreamException {
+ MTOMXMLStreamWriter xmlWriter =
+ new MTOMXMLStreamWriter(StAXUtils.createXMLStreamWriter(writer));
+ xmlWriter.setOutputFormat(format);
+ serialize(xmlWriter);
+ xmlWriter.flush();
+ }
+
+ @Override
+ public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException {
+ StreamingOMSerializer serializer = new StreamingOMSerializer();
+ serializer.serialize(getReader(), xmlWriter);
+ }
+
+ public XMLStreamReader getReader() throws XMLStreamException {
+ return new WrappedTextNodeStreamReader(wrapperElementName, reader);
+ }
+
+ public Object getObject() {
+ return null;
+ }
+
+ public boolean isDestructiveRead() {
+ return true;
+ }
+
+ public boolean isDestructiveWrite() {
+ return true;
+ }
+
+ public byte[] getXMLBytes(String encoding) throws UnsupportedEncodingException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void close() {
+ try {
+ reader.close();
+ } catch (IOException ex) {
+ // Ignore
+ }
+ }
+
+ public OMDataSourceExt copy() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeStreamReader.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeStreamReader.java
new file mode 100644
index 0000000..566cd7c
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/format/WrappedTextNodeStreamReader.java
@@ -0,0 +1,437 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Collections;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.impl.EmptyOMLocation;
+import org.apache.axiom.om.impl.llom.util.NamespaceContextImpl;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * {@link XMLInputStreamReader} implementation that
+ * represents a text node wrapped inside an element. The text data is provided by a
+ * {@link java.io.Reader Reader}.
+ * <p>
+ * It will produce the following sequence of XML events:
+ * <ul>
+ * <li>START_DOCUMENT</li>
+ * <li>START_ELEMENT</li>
+ * <li>(CHARACTER)*</li>
+ * <li>END_ELEMENT</li>
+ * <li>END_DOCMENT</li>
+ * </ul>
+ * The class is implemented as a simple state machine, where the state is identified
+ * by the current event type. The initial state is <tt>START_DOCUMENT</tt> and the
+ * following transitions are triggered by {@link #next()}:
+ * <ul>
+ * <li>START_DOCUMENT → START_ELEMENT</li>
+ * <li>START_ELEMENT → END_ELEMENT (if character stream is empty)</li>
+ * <li>START_ELEMENT → CHARACTERS (if character stream is not empty)</li>
+ * <li>CHARACTERS → CHARACTERS (if data available in stream)</li>
+ * <li>CHARACTERS → END_ELEMENT (if end of stream reached)</li>
+ * <li>END_ELEMENT → END_DOCUMENT</li>
+ * </ul>
+ * Additionally, {@link #getElementText()} triggers the following transition:
+ * <ul>
+ * <li>START_ELEMENT → END_ELEMENT</li>
+ * </ul>
+ * Note that since multiple consecutive CHARACTERS events may be returned, this
+ * "parser" is not coalescing.
+ *
+ */
+// TODO: This class has been copied from Synapse (package org.apache.synapse.util).
+// Once it has been moved to Axis2 or Axiom, remove the duplicate from Synapse.
+public class WrappedTextNodeStreamReader implements XMLStreamReader {
+ /**
+ * Location object returned by {@link #getLocation()}.
+ * It always returns -1 for the location and null for the publicId and systemId.
+ */
+ private final static Location EMPTY_LOCATION = new EmptyOMLocation();
+
+ /**
+ * The qualified name of the wrapper element.
+ */
+ private final QName wrapperElementName;
+
+ /**
+ * The Reader object that represents the text data.
+ */
+ private final Reader reader;
+
+ /**
+ * The maximum number of characters to return for each CHARACTER event.
+ */
+ private final int chunkSize;
+
+ /**
+ * The type of the current XML event.
+ */
+ private int eventType = START_DOCUMENT;
+
+ /**
+ * The character data for the current event. This is only set if the current
+ * event is a CHARACTER event. The size of the array is determined by
+ * {@link #chunkSize}
+ */
+ private char[] charData;
+
+ /**
+ * The length of the character data in {@link #charData}.
+ */
+ private int charDataLength;
+
+ /**
+ * The namespace context applicable in the scope of the wrapper element.
+ * Beside the default mappings for xml and xmlns, it only contains the
+ * mapping for the namespace of the wrapper element.
+ * This attribute is initialized lazily by {@link #getNamespaceContext()}.
+ */
+ private NamespaceContext namespaceContext;
+
+ /**
+ * Create a new instance.
+ *
+ * @param wrapperElementName the qualified name of the wrapper element
+ * @param reader the Reader object holding the character data to be wrapped
+ * @param chunkSize the maximum number of characters that are returned for each CHARACTER event
+ */
+ public WrappedTextNodeStreamReader(QName wrapperElementName, Reader reader, int chunkSize) {
+ this.wrapperElementName = wrapperElementName;
+ this.reader = reader;
+ this.chunkSize = chunkSize;
+ }
+
+ /**
+ * Create a new instance with chunk size 4096.
+ *
+ * @param wrapperElementName the qualified name of the wrapper element
+ * @param reader the Reader object holding the character data to be wrapped
+ */
+ public WrappedTextNodeStreamReader(QName wrapperElementName, Reader reader) {
+ this(wrapperElementName, reader, 4096);
+ }
+
+ public Object getProperty(String name) throws IllegalArgumentException {
+ // We don't define any properties
+ return null;
+ }
+
+ //
+ // Methods to manipulate the parser state
+ //
+
+ public boolean hasNext() throws XMLStreamException {
+ return eventType != END_DOCUMENT;
+ }
+
+ public int next() throws XMLStreamException {
+ // Determine next event type based on current event type. If current event type
+ // is START_ELEMENT or CHARACTERS, pull new data from the reader.
+ switch (eventType) {
+ case START_DOCUMENT:
+ eventType = START_ELEMENT;
+ break;
+ case START_ELEMENT:
+ charData = new char[chunkSize];
+ // No break here!
+ case CHARACTERS:
+ try {
+ charDataLength = reader.read(charData);
+ }
+ catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ if (charDataLength == -1) {
+ charData = null;
+ eventType = END_ELEMENT;
+ } else {
+ eventType = CHARACTERS;
+ }
+ break;
+ case END_ELEMENT:
+ eventType = END_DOCUMENT;
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return eventType;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ // We don't have white space, comments or processing instructions
+ throw new XMLStreamException("Current event is not white space");
+ }
+
+ public int getEventType() {
+ return eventType;
+ }
+
+ public boolean isStartElement() { return eventType == START_ELEMENT; }
+ public boolean isEndElement() { return eventType == END_ELEMENT; }
+ public boolean isCharacters() { return eventType == CHARACTERS; }
+ public boolean isWhiteSpace() { return false; }
+ public boolean hasText() { return eventType == CHARACTERS; }
+ public boolean hasName() { return eventType == START_ELEMENT || eventType == END_ELEMENT; }
+
+ public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+ if (type != eventType
+ || (namespaceURI != null && !namespaceURI.equals(getNamespaceURI()))
+ || (localName != null && !namespaceURI.equals(getLocalName()))) {
+ throw new XMLStreamException("Unexpected event type");
+ }
+ }
+
+ public Location getLocation() {
+ // We do not support location information
+ return EMPTY_LOCATION;
+ }
+
+ public void close() throws XMLStreamException {
+ // Javadoc says that this method should not close the underlying input source,
+ // but we need to close the reader somewhere.
+ try {
+ reader.close();
+ }
+ catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ }
+
+ //
+ // Methods related to the xml declaration.
+ //
+
+ public String getEncoding() {
+ // Encoding is not known (not relevant?)
+ return null;
+ }
+
+ public String getCharacterEncodingScheme() {
+ // Encoding is not known (not relevant?)
+ return null;
+ }
+
+ public String getVersion() {
+ // Version is not relevant
+ return null;
+ }
+
+ public boolean standaloneSet() {
+ return false;
+ }
+
+ public boolean isStandalone() {
+ return true;
+ }
+
+ //
+ // Methods related to the namespace context
+ //
+
+ public NamespaceContext getNamespaceContext() {
+ if (namespaceContext == null) {
+ namespaceContext = new NamespaceContextImpl(Collections.singletonMap(wrapperElementName.getPrefix(), wrapperElementName.getNamespaceURI()));
+ }
+ return namespaceContext;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ String namespaceURI = getNamespaceContext().getNamespaceURI(prefix);
+ // NamespaceContext#getNamespaceURI and XMLStreamReader#getNamespaceURI have slightly
+ // different semantics for unbound prefixes.
+ return namespaceURI.equals(XMLConstants.NULL_NS_URI) ? null : prefix;
+ }
+
+ //
+ // Methods related to elements
+ //
+
+ private void checkStartElement() {
+ if (eventType != START_ELEMENT) {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(String namespaceURI, String localName) {
+ checkStartElement();
+ return null;
+ }
+
+ public int getAttributeCount() {
+ checkStartElement();
+ return 0;
+ }
+
+ public QName getAttributeName(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributeLocalName(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributePrefix(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributeNamespace(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributeType(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributeValue(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public boolean isAttributeSpecified(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ private void checkElement() {
+ if (eventType != START_ELEMENT && eventType != END_ELEMENT) {
+ throw new IllegalStateException();
+ }
+ }
+
+ public QName getName() {
+ return null;
+ }
+
+ public String getLocalName() {
+ checkElement();
+ return wrapperElementName.getLocalPart();
+ }
+
+ public String getPrefix() {
+ return wrapperElementName.getPrefix();
+ }
+
+ public String getNamespaceURI() {
+ checkElement();
+ return wrapperElementName.getNamespaceURI();
+ }
+
+ public int getNamespaceCount() {
+ checkElement();
+ // There is one namespace declared on the wrapper element
+ return 1;
+ }
+
+ public String getNamespacePrefix(int index) {
+ checkElement();
+ if (index == 0) {
+ return wrapperElementName.getPrefix();
+ } else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public String getNamespaceURI(int index) {
+ checkElement();
+ if (index == 0) {
+ return wrapperElementName.getNamespaceURI();
+ } else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (eventType == START_ELEMENT) {
+ // Actually the purpose of this class is to avoid storing
+ // the character data entirely in memory, but if the caller
+ // wants a String, we don't have the choice...
+ try {
+ String result = IOUtils.toString(reader);
+ eventType = END_ELEMENT;
+ return result;
+ }
+ catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ } else {
+ throw new XMLStreamException("Current event is not a START_ELEMENT");
+ }
+ }
+
+ private void checkCharacters() {
+ if (eventType != CHARACTERS) {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getText() {
+ checkCharacters();
+ return new String(charData, 0, charDataLength);
+ }
+
+ public char[] getTextCharacters() {
+ checkCharacters();
+ return charData;
+ }
+
+ public int getTextStart() {
+ checkCharacters();
+ return 0;
+ }
+
+ public int getTextLength() {
+ checkCharacters();
+ return charDataLength;
+ }
+
+ public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
+ checkCharacters();
+ int c = Math.min(charDataLength-sourceStart, length);
+ System.arraycopy(charData, sourceStart, target, targetStart, c);
+ return c;
+ }
+
+ //
+ // Methods related to processing instructions
+ //
+
+ public String getPIData() {
+ throw new IllegalStateException();
+ }
+
+ public String getPITarget() {
+ throw new IllegalStateException();
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractPollTableEntry.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractPollTableEntry.java
new file mode 100644
index 0000000..53c9a8b
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractPollTableEntry.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import java.util.TimerTask;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.description.ParameterInclude;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public abstract class AbstractPollTableEntry extends ProtocolEndpoint {
+ private static final Log log = LogFactory.getLog(AbstractPollTableEntry.class);
+
+ // status of last scan
+ public static final int SUCCSESSFUL = 0;
+ public static final int WITH_ERRORS = 1;
+ public static final int FAILED = 2;
+ public static final int NONE = 3;
+
+ /** next poll time */
+ private long nextPollTime;
+ /** last poll performed at */
+ private long lastPollTime;
+ /** duration in ms between successive polls */
+ private long pollInterval;
+ /** state of the last poll */
+ private int lastPollState;
+ /** can polling occur in parallel? */
+ private boolean concurrentPollingAllowed = false;
+ /** The timer task that will trigger the next poll */
+ TimerTask timerTask;
+ /** Flag indicating whether polling has been canceled. */
+ boolean canceled;
+
+ public long getNextPollTime() {
+ return nextPollTime;
+ }
+
+ public void setNextPollTime(long nextPollTime) {
+ this.nextPollTime = nextPollTime;
+ }
+
+ public long getLastPollTime() {
+ return lastPollTime;
+ }
+
+ public void setLastPollTime(long lastPollTime) {
+ this.lastPollTime = lastPollTime;
+ }
+
+ public long getPollInterval() {
+ return pollInterval;
+ }
+
+ public void setPollInterval(long pollInterval) {
+ this.pollInterval = pollInterval;
+ }
+
+ public int getLastPollState() {
+ return lastPollState;
+ }
+
+ public void setLastPollState(int lastPollState) {
+ this.lastPollState = lastPollState;
+ }
+
+ public boolean isConcurrentPollingAllowed() {
+ return concurrentPollingAllowed;
+ }
+
+ public void setConcurrentPollingAllowed(boolean concurrentPollingAllowed) {
+ this.concurrentPollingAllowed = concurrentPollingAllowed;
+ }
+
+ @Override
+ public boolean loadConfiguration(ParameterInclude params) throws AxisFault {
+ Parameter param = params.getParameter(BaseConstants.TRANSPORT_POLL_INTERVAL);
+ pollInterval = BaseConstants.DEFAULT_POLL_INTERVAL;
+ if (param != null && param.getValue() instanceof String) {
+ String s = (String)param.getValue();
+ int multiplier;
+ if (s.endsWith("ms")) {
+ s = s.substring(0, s.length()-2);
+ multiplier = 1;
+ } else {
+ multiplier = 1000;
+ }
+ try {
+ pollInterval = Integer.parseInt(s) * multiplier;
+ } catch (NumberFormatException e) {
+ log.error("Invalid poll interval : " + param.getValue() + ", default to : "
+ + (BaseConstants.DEFAULT_POLL_INTERVAL / 1000) + "sec", e);
+ }
+ }
+ return true;
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractPollingTransportListener.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractPollingTransportListener.java
new file mode 100644
index 0000000..67489e5
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractPollingTransportListener.java
@@ -0,0 +1,169 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.description.TransportInDescription;
+import org.apache.axis2.AxisFault;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TimerTask;
+import java.util.Timer;
+
+public abstract class AbstractPollingTransportListener<T extends AbstractPollTableEntry>
+ extends AbstractTransportListenerEx<T> {
+
+ /** The main timer. */
+ private Timer timer;
+ /** Keep the list of endpoints and poll durations */
+ private final List<T> endpoints = new ArrayList<T>();
+
+ @Override
+ public void init(ConfigurationContext cfgCtx,
+ TransportInDescription transportIn) throws AxisFault {
+
+ timer = new Timer("PollTimer");
+ super.init(cfgCtx, transportIn);
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ timer.cancel();
+ timer = null;
+ }
+
+ /**
+ * Schedule a repeated poll at the specified interval for a given service.
+ * The method will schedule a single-shot timer task with executes a work
+ * task on the worker pool. At the end of this work task, a new timer task
+ * is scheduled for the next poll (except if the polling for the service
+ * has been canceled). This effectively schedules the poll repeatedly
+ * with fixed delay.
+ * @param entry the poll table entry with the configuration for the service
+ * @param pollInterval the interval between successive polls in milliseconds
+ */
+ void schedulePoll(final T entry) {
+ final long pollInterval = entry.getPollInterval();
+ TimerTask timerTask = new TimerTask() {
+ @Override
+ public void run() {
+ workerPool.execute(new Runnable() {
+ public void run() {
+ if (state == BaseConstants.PAUSED) {
+ if (log.isDebugEnabled()) {
+ log.debug("Transport " + getTransportName() +
+ " poll trigger : Transport is currently paused..");
+ }
+ } else {
+ poll(entry);
+ }
+ }
+ });
+ }
+ };
+ entry.timerTask = timerTask;
+ if (entry.isConcurrentPollingAllowed()) {
+ timer.scheduleAtFixedRate(timerTask, pollInterval, pollInterval);
+ } else {
+ timer.schedule(timerTask, pollInterval);
+ }
+ }
+
+ @Override
+ protected void startEndpoint(T endpoint) throws AxisFault {
+ schedulePoll(endpoint);
+ }
+
+ @Override
+ protected void stopEndpoint(T endpoint) {
+ synchronized (endpoint) {
+ endpoint.timerTask.cancel();
+ endpoint.canceled = true;
+ }
+ }
+
+ protected abstract void poll(T entry);
+
+ protected void onPollCompletion(T entry) {
+ if (!entry.isConcurrentPollingAllowed()) {
+ synchronized (entry) {
+ if (!entry.canceled) {
+ schedulePoll(entry);
+ }
+ }
+ }
+ }
+
+ /**
+ * method to log a failure to the log file and to update the last poll status and time
+ * @param msg text for the log message
+ * @param e optional exception encountered or null
+ * @param entry the PollTableEntry
+ */
+ protected void processFailure(String msg, Exception e, T entry) {
+ if (e == null) {
+ log.error(msg);
+ } else {
+ log.error(msg, e);
+ }
+ long now = System.currentTimeMillis();
+ entry.setLastPollState(AbstractPollTableEntry.FAILED);
+ entry.setLastPollTime(now);
+ entry.setNextPollTime(now + entry.getPollInterval());
+ onPollCompletion(entry);
+ }
+
+ // -- jmx/management methods--
+ /**
+ * Pause the listener - Stop accepting/processing new messages, but continues processing existing
+ * messages until they complete. This helps bring an instance into a maintenence mode
+ * @throws org.apache.axis2.AxisFault on error
+ */
+ public void pause() throws AxisFault {
+ if (state != BaseConstants.STARTED) return;
+ state = BaseConstants.PAUSED;
+ log.info("Listener paused");
+ }
+
+ /**
+ * Resume the lister - Brings the lister into active mode back from a paused state
+ * @throws AxisFault on error
+ */
+ public void resume() throws AxisFault {
+ if (state != BaseConstants.PAUSED) return;
+ state = BaseConstants.STARTED;
+ log.info("Listener resumed");
+ }
+
+ /**
+ * Stop processing new messages, and wait the specified maximum time for in-flight
+ * requests to complete before a controlled shutdown for maintenence
+ *
+ * @param millis a number of milliseconds to wait until pending requests are allowed to complete
+ * @throws AxisFault on error
+ */
+ public void maintenenceShutdown(long millis) throws AxisFault {
+ if (state != BaseConstants.STARTED) return;
+ stop();
+ state = BaseConstants.STOPPED;
+ log.info("Listener shutdown");
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportListener.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportListener.java
new file mode 100644
index 0000000..012872a
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportListener.java
@@ -0,0 +1,563 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.SessionContext;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.*;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.util.MessageContextBuilder;
+import org.apache.axis2.transport.base.threads.WorkerPool;
+import org.apache.axis2.transport.base.threads.WorkerPoolFactory;
+import org.apache.axis2.transport.base.tracker.AxisServiceFilter;
+import org.apache.axis2.transport.base.tracker.AxisServiceTracker;
+import org.apache.axis2.transport.base.tracker.AxisServiceTrackerListener;
+import org.apache.axis2.transport.TransportListener;
+import org.apache.axis2.engine.AxisEngine;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.axiom.om.util.UUIDGenerator;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.util.*;
+import java.lang.management.ManagementFactory;
+
+public abstract class AbstractTransportListener implements TransportListener {
+
+ /** the reference to the actual commons logger to be used for log messages */
+ protected Log log = null;
+
+ /** the axis2 configuration context */
+ protected ConfigurationContext cfgCtx = null;
+
+ /** transport in description */
+ private TransportInDescription transportIn = null;
+ /** transport out description */
+ private TransportOutDescription transportOut = null;
+ /** state of the listener */
+ protected int state = BaseConstants.STOPPED;
+ /** is this transport non-blocking? */
+ protected boolean isNonBlocking = false;
+ /**
+ * Service tracker used to invoke {@link #internalStartListeningForService(AxisService)}
+ * and {@link #internalStopListeningForService(AxisService)}. */
+ private AxisServiceTracker serviceTracker;
+
+ /** the thread pool to execute actual poll invocations */
+ protected WorkerPool workerPool = null;
+ /** use the thread pool available in the axis2 configuration context */
+ protected boolean useAxis2ThreadPool = false;
+ /** JMX support */
+ private TransportMBeanSupport mbeanSupport;
+ /** Metrics collector for this transport */
+ protected MetricsCollector metrics = new MetricsCollector();
+ /** Transport Configuration for the respective transports */
+ protected TransportConfiguration config;
+
+ /**
+ * A constructor that makes subclasses pick up the correct logger
+ */
+ protected AbstractTransportListener() {
+ log = LogFactory.getLog(this.getClass());
+ }
+
+ /**
+ * Initialize the generic transport. Sets up the transport and the thread pool to be used
+ * for message processing. Also creates an AxisObserver that gets notified of service
+ * life cycle events for the transport to act on
+ * @param cfgCtx the axis configuration context
+ * @param transportIn the transport-in description
+ * @throws AxisFault on error
+ */
+ public void init(ConfigurationContext cfgCtx, TransportInDescription transportIn)
+ throws AxisFault {
+
+ this.cfgCtx = cfgCtx;
+ this.transportIn = transportIn;
+ this.transportOut = cfgCtx.getAxisConfiguration().getTransportOut(getTransportName());
+ this.config = TransportConfiguration.getConfiguration(getTransportName());
+
+ if (useAxis2ThreadPool) {
+ //this.workerPool = cfgCtx.getThreadPool(); not yet implemented
+ throw new AxisFault("Unsupported thread pool for task execution - Axis2 thread pool");
+ } else {
+ if (this.workerPool == null) { // FIXME <-- workaround for AXIS2-4552
+ this.workerPool = WorkerPoolFactory.getWorkerPool(
+ config.getServerCoreThreads(),
+ config.getServerMaxThreads(),
+ config.getServerKeepalive(),
+ config.getServerQueueLen(),
+ getTransportName() + "Server Worker thread group",
+ getTransportName() + "-Worker");
+ }
+
+ }
+
+ // register to receive updates on services for lifetime management
+ serviceTracker = new AxisServiceTracker(
+ cfgCtx.getAxisConfiguration(),
+ new AxisServiceFilter() {
+ public boolean matches(AxisService service) {
+ return !service.getName().startsWith("__") // these are "private" services
+ && BaseUtils.isUsingTransport(service, getTransportName());
+ }
+ },
+ new AxisServiceTrackerListener() {
+ public void serviceAdded(AxisService service) {
+ internalStartListeningForService(service);
+ }
+
+ public void serviceRemoved(AxisService service) {
+ internalStopListeningForService(service);
+ }
+ });
+
+ // register with JMX
+ if (mbeanSupport == null) { // FIXME <-- workaround for AXIS2-4552
+ mbeanSupport = new TransportMBeanSupport(this, getTransportName());
+ mbeanSupport.register();
+ }
+
+ }
+
+ public void destroy() {
+ try {
+ if (state == BaseConstants.STARTED) {
+ try {
+ stop();
+ } catch (AxisFault ignore) {
+ log.warn("Error stopping the transport : " + getTransportName());
+ }
+ }
+ } finally {
+ state = BaseConstants.STOPPED;
+ mbeanSupport.unregister();
+ }
+ try {
+ workerPool.shutdown(10000);
+ } catch (InterruptedException ex) {
+ log.warn("Thread interrupted while waiting for worker pool to shut down");
+ }
+ }
+
+ public void stop() throws AxisFault {
+ if (state == BaseConstants.STARTED) {
+ state = BaseConstants.STOPPED;
+ // cancel receipt of service lifecycle events
+ log.info(getTransportName().toUpperCase() + " Listener Shutdown");
+ serviceTracker.stop();
+ }
+ }
+
+ public void start() throws AxisFault {
+ if (state != BaseConstants.STARTED) {
+ state = BaseConstants.STARTED;
+ // register to receive updates on services for lifetime management
+ // cfgCtx.getAxisConfiguration().addObservers(axisObserver);
+ log.info(getTransportName().toUpperCase() + " Listener started");
+ // iterate through deployed services and start
+ serviceTracker.start();
+ }
+ }
+
+ public EndpointReference[] getEPRsForService(String serviceName, String ip) throws AxisFault {
+ return getEPRsForService(serviceName);
+ }
+
+ protected EndpointReference[] getEPRsForService(String serviceName) {
+ return null;
+ }
+
+ public void disableTransportForService(AxisService service) {
+
+ log.warn("Disabling the " + getTransportName() + " transport for the service "
+ + service.getName() + ", because it is not configured properly for the service");
+
+ if (service.isEnableAllTransports()) {
+ ArrayList<String> exposedTransports = new ArrayList<String>();
+ for(Object obj: cfgCtx.getAxisConfiguration().getTransportsIn().values()) {
+ String transportName = ((TransportInDescription) obj).getName();
+ if (!transportName.equals(getTransportName())) {
+ exposedTransports.add(transportName);
+ }
+ }
+ service.setEnableAllTransports(false);
+ service.setExposedTransports(exposedTransports);
+ } else {
+ service.removeExposedTransport(getTransportName());
+ }
+ }
+
+ void internalStartListeningForService(AxisService service) {
+ String serviceName = service.getName();
+ try {
+ startListeningForService(service);
+ } catch (AxisFault ex) {
+ String transportName = getTransportName().toUpperCase();
+ String msg = "Unable to configure the service " + serviceName + " for the " +
+ transportName + " transport: " + ex.getMessage() + ". " +
+ "This service is being marked as faulty and will not be available over the " +
+ transportName + " transport.";
+ // Only log the message at level WARN and log the full stack trace at level DEBUG.
+ // TODO: We should have a way to distinguish a missing configuration
+ // from an error. This may be addressed when implementing the enhancement
+ // described in point 3 of http://markmail.org/message/umhenrurlrekk5jh
+ log.warn(msg);
+ log.debug("Disabling service " + serviceName + " for the " + transportName +
+ "transport", ex);
+ BaseUtils.markServiceAsFaulty(serviceName, msg, service.getAxisConfiguration());
+ disableTransportForService(service);
+ return;
+ } catch (Throwable ex) {
+ String msg = "Unexpected error when configuring service " + serviceName +
+ " for the " + getTransportName().toUpperCase() + " transport. It will be" +
+ " disabled for this transport and marked as faulty.";
+ log.error(msg, ex);
+ BaseUtils.markServiceAsFaulty(serviceName, msg, service.getAxisConfiguration());
+ disableTransportForService(service);
+ return;
+ }
+ registerMBean(new TransportListenerEndpointView(this, serviceName),
+ getEndpointMBeanName(serviceName));
+ }
+
+ void internalStopListeningForService(AxisService service) {
+ unregisterMBean(getEndpointMBeanName(service.getName()));
+ stopListeningForService(service);
+ }
+
+ protected abstract void startListeningForService(AxisService service) throws AxisFault;
+
+ protected abstract void stopListeningForService(AxisService service);
+
+ /**
+ * This is a deprecated method in Axis2 and this default implementation returns the first
+ * result from the getEPRsForService() method
+ */
+ public EndpointReference getEPRForService(String serviceName, String ip) throws AxisFault {
+ return getEPRsForService(serviceName, ip)[0];
+ }
+
+ public SessionContext getSessionContext(MessageContext messageContext) {
+ return null;
+ }
+
+ /**
+ * Create a new axis MessageContext for an incoming message through this transport
+ * @return the newly created message context
+ */
+ public MessageContext createMessageContext() {
+ MessageContext msgCtx = new MessageContext();
+ msgCtx.setConfigurationContext(cfgCtx);
+
+ msgCtx.setIncomingTransportName(getTransportName());
+ msgCtx.setTransportOut(transportOut);
+ msgCtx.setTransportIn(transportIn);
+ msgCtx.setServerSide(true);
+ msgCtx.setMessageID(UUIDGenerator.getUUID());
+
+ // There is a discrepency in what I thought, Axis2 spawns a nes threads to
+ // send a message is this is TRUE - and I want it to be the other way
+ msgCtx.setProperty(MessageContext.TRANSPORT_NON_BLOCKING, Boolean.valueOf(!isNonBlocking));
+
+ // are these relevant?
+ //msgCtx.setServiceGroupContextId(UUIDGenerator.getUUID());
+ // this is required to support Sandesha 2
+ //msgContext.setProperty(RequestResponseTransport.TRANSPORT_CONTROL,
+ // new HttpCoreRequestResponseTransport(msgContext));
+
+ return msgCtx;
+ }
+
+ /**
+ * Process a new incoming message through the axis engine
+ * @param msgCtx the axis MessageContext
+ * @param trpHeaders the map containing transport level message headers
+ * @param soapAction the optional soap action or null
+ * @param contentType the optional content-type for the message
+ */
+ public void handleIncomingMessage(
+ MessageContext msgCtx, Map trpHeaders,
+ String soapAction, String contentType) throws AxisFault {
+
+ // set the soapaction if one is available via a transport header
+ if (soapAction != null) {
+ msgCtx.setSoapAction(soapAction);
+ }
+
+ // set the transport headers to the message context
+ msgCtx.setProperty(MessageContext.TRANSPORT_HEADERS, trpHeaders);
+
+ // send the message context through the axis engine
+ try {
+ // check if an Axis2 callback has been registered for this message
+ Map callBackMap = (Map) msgCtx.getConfigurationContext().
+ getProperty(BaseConstants.CALLBACK_TABLE);
+ // FIXME: transport headers are protocol specific; the correlation ID should be
+ // passed as argument to this method
+ Object replyToMessageID = trpHeaders.get(BaseConstants.HEADER_IN_REPLY_TO);
+ // if there is a callback registerd with this replyto ID then this has to
+ // be handled as a synchronous incoming message, via the
+ if (replyToMessageID != null && callBackMap != null &&
+ callBackMap.get(replyToMessageID) != null) {
+
+ SynchronousCallback synchronousCallback =
+ (SynchronousCallback) callBackMap.get(replyToMessageID);
+ synchronousCallback.setInMessageContext(msgCtx);
+ callBackMap.remove(replyToMessageID);
+ } else {
+ AxisEngine.receive(msgCtx);
+ }
+
+ } catch (AxisFault e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Error receiving message", e);
+ }
+ if (msgCtx.isServerSide()) {
+ AxisEngine.sendFault(MessageContextBuilder.createFaultMessageContext(msgCtx, e));
+ }
+ }
+ }
+
+ protected void handleException(String msg, Exception e) throws AxisFault {
+ log.error(msg, e);
+ throw new AxisFault(msg, e);
+ }
+
+ protected void logException(String msg, Exception e) {
+ log.error(msg, e);
+ }
+
+ public String getTransportName() {
+ return transportIn.getName();
+ }
+
+ public ConfigurationContext getConfigurationContext() {
+ return cfgCtx;
+ }
+
+ public MetricsCollector getMetricsCollector() {
+ return metrics;
+ }
+
+ // -- jmx/management methods--
+ /**
+ * Pause the listener - Stop accepting/processing new messages, but continues processing existing
+ * messages until they complete. This helps bring an instance into a maintenence mode
+ * @throws AxisFault on error
+ */
+ public void pause() throws AxisFault {}
+ /**
+ * Resume the lister - Brings the lister into active mode back from a paused state
+ * @throws AxisFault on error
+ */
+ public void resume() throws AxisFault {}
+
+ /**
+ * Stop processing new messages, and wait the specified maximum time for in-flight
+ * requests to complete before a controlled shutdown for maintenence
+ *
+ * @param millis a number of milliseconds to wait until pending requests are allowed to complete
+ * @throws AxisFault on error
+ */
+ public void maintenenceShutdown(long millis) throws AxisFault {}
+
+ /**
+ * Returns the number of active threads processing messages
+ * @return number of active threads processing messages
+ */
+ public int getActiveThreadCount() {
+ return workerPool.getActiveCount();
+ }
+
+ /**
+ * Return the number of requests queued in the thread pool
+ * @return queue size
+ */
+ public int getQueueSize() {
+ return workerPool.getQueueSize();
+ }
+
+ public long getMessagesReceived() {
+ if (metrics != null) {
+ return metrics.getMessagesReceived();
+ }
+ return -1;
+ }
+
+ public long getFaultsReceiving() {
+ if (metrics != null) {
+ return metrics.getFaultsReceiving();
+ }
+ return -1;
+ }
+
+ public long getBytesReceived() {
+ if (metrics != null) {
+ return metrics.getBytesReceived();
+ }
+ return -1;
+ }
+
+ public long getMessagesSent() {
+ if (metrics != null) {
+ return metrics.getMessagesSent();
+ }
+ return -1;
+ }
+
+ public long getFaultsSending() {
+ if (metrics != null) {
+ return metrics.getFaultsSending();
+ }
+ return -1;
+ }
+
+ public long getBytesSent() {
+ if (metrics != null) {
+ return metrics.getBytesSent();
+ }
+ return -1;
+ }
+
+ public long getTimeoutsReceiving() {
+ if (metrics != null) {
+ return metrics.getTimeoutsReceiving();
+ }
+ return -1;
+ }
+
+ public long getTimeoutsSending() {
+ if (metrics != null) {
+ return metrics.getTimeoutsSending();
+ }
+ return -1;
+ }
+
+ public long getMinSizeReceived() {
+ if (metrics != null) {
+ return metrics.getMinSizeReceived();
+ }
+ return -1;
+ }
+
+ public long getMaxSizeReceived() {
+ if (metrics != null) {
+ return metrics.getMaxSizeReceived();
+ }
+ return -1;
+ }
+
+ public double getAvgSizeReceived() {
+ if (metrics != null) {
+ return metrics.getAvgSizeReceived();
+ }
+ return -1;
+ }
+
+ public long getMinSizeSent() {
+ if (metrics != null) {
+ return metrics.getMinSizeSent();
+ }
+ return -1;
+ }
+
+ public long getMaxSizeSent() {
+ if (metrics != null) {
+ return metrics.getMaxSizeSent();
+ }
+ return -1;
+ }
+
+ public double getAvgSizeSent() {
+ if (metrics != null) {
+ return metrics.getAvgSizeSent();
+ }
+ return -1;
+ }
+
+ public Map getResponseCodeTable() {
+ if (metrics != null) {
+ return metrics.getResponseCodeTable();
+ }
+ return null;
+ }
+
+ public void resetStatistics() {
+ if (metrics != null) {
+ metrics.reset();
+ }
+ }
+
+ public long getLastResetTime() {
+ if (metrics != null) {
+ return metrics.getLastResetTime();
+ }
+ return -1;
+ }
+
+ public long getMetricsWindow() {
+ if (metrics != null) {
+ return System.currentTimeMillis() - metrics.getLastResetTime();
+ }
+ return -1;
+ }
+
+ private String getEndpointMBeanName(String serviceName) {
+ return mbeanSupport.getMBeanName() + ",Group=Services,Service=" + serviceName;
+ }
+
+ /**
+ * Utility method to allow transports to register MBeans
+ * @param mbeanInstance bean instance
+ * @param objectName name
+ */
+ private void registerMBean(Object mbeanInstance, String objectName) {
+ try {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ ObjectName name = new ObjectName(objectName);
+ Set set = mbs.queryNames(name, null);
+ if (set != null && set.isEmpty()) {
+ mbs.registerMBean(mbeanInstance, name);
+ } else {
+ mbs.unregisterMBean(name);
+ mbs.registerMBean(mbeanInstance, name);
+ }
+ } catch (Exception e) {
+ log.warn("Error registering a MBean with objectname ' " + objectName +
+ " ' for JMX management", e);
+ }
+ }
+
+ private void unregisterMBean(String objectName) {
+ try {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ ObjectName objName = new ObjectName(objectName);
+ if (mbs.isRegistered(objName)) {
+ mbs.unregisterMBean(objName);
+ }
+ } catch (Exception e) {
+ log.warn("Error un-registering a MBean with objectname ' " + objectName +
+ " ' for JMX management", e);
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportListenerEx.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportListenerEx.java
new file mode 100644
index 0000000..667b323
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportListenerEx.java
@@ -0,0 +1,137 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.TransportInDescription;
+
+/**
+ * Partial implementation of {@link AbstractTransportListener} with a higher level
+ * of abstraction. It maintains the mapping between services and protocol specific
+ * endpoints.
+ * <p>
+ * Note: the intention is to eventually merge the code in this class into
+ * {@link AbstractTransportListener}
+ *
+ * @param <E> the type of protocol endpoint for this transport
+ */
+public abstract class AbstractTransportListenerEx<E extends ProtocolEndpoint>
+ extends AbstractTransportListener {
+
+ /** A Map of service name to the protocol endpoints */
+ private List<E> endpoints = new ArrayList<E>();
+
+ @Override
+ public void init(ConfigurationContext cfgCtx,
+ TransportInDescription transportIn) throws AxisFault {
+
+ super.init(cfgCtx, transportIn);
+
+ // Create endpoint configured at transport level (if available)
+ E endpoint = createEndpoint();
+ endpoint.init(this, null);
+ if (endpoint.loadConfiguration(transportIn)) {
+ startEndpoint(endpoint);
+ endpoints.add(endpoint);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ // Explicitly stop all endpoints not predispatched to services. All other endpoints will
+ // be stopped by stopListeningForService.
+ List<E> endpointsToStop = new ArrayList<E>();
+ for (E endpoint : endpoints) {
+ if (endpoint.getService() == null) {
+ endpointsToStop.add(endpoint);
+ }
+ }
+ for (E endpoint : endpointsToStop) {
+ stopEndpoint(endpoint);
+ endpoints.remove(endpoint);
+ }
+
+ super.destroy();
+ }
+
+ @Override
+ public EndpointReference[] getEPRsForService(String serviceName, String ip) throws AxisFault {
+ //Strip out the operation name
+ if (serviceName.indexOf('/') != -1) {
+ serviceName = serviceName.substring(0, serviceName.indexOf('/'));
+ }
+ // strip out the endpoint name if present
+ if (serviceName.indexOf('.') != -1) {
+ serviceName = serviceName.substring(0, serviceName.indexOf('.'));
+ }
+ for (E endpoint : endpoints) {
+ AxisService service = endpoint.getService();
+ if (service != null) {
+ if (service.getName().equals(serviceName)) {
+ return endpoint.getEndpointReferences(ip);
+ }
+ }
+ }
+ return null;
+ }
+
+ public final Collection<E> getEndpoints() {
+ return Collections.unmodifiableCollection(endpoints);
+ }
+
+ protected abstract E createEndpoint();
+
+ @Override
+ protected final void startListeningForService(AxisService service) throws AxisFault {
+ E endpoint = createEndpoint();
+ endpoint.init(this, service);
+ if (endpoint.loadConfiguration(service)) {
+ startEndpoint(endpoint);
+ endpoints.add(endpoint);
+ } else {
+ throw new AxisFault("Service doesn't have configuration information for transport " +
+ getTransportName());
+ }
+ }
+
+ protected abstract void startEndpoint(E endpoint) throws AxisFault;
+
+ @Override
+ protected final void stopListeningForService(AxisService service) {
+ for (E endpoint : endpoints) {
+ if (service == endpoint.getService()) {
+ stopEndpoint(endpoint);
+ endpoints.remove(endpoint);
+ return;
+ }
+ }
+ log.error("Unable to stop service : " + service.getName() +
+ " - unable to find the corresponding protocol endpoint");
+ }
+
+ protected abstract void stopEndpoint(E endpoint);
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportSender.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportSender.java
new file mode 100644
index 0000000..4d3b4d0
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/AbstractTransportSender.java
@@ -0,0 +1,417 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.Constants;
+import org.apache.axis2.wsdl.WSDLConstants;
+import org.apache.axis2.util.MessageContextBuilder;
+import org.apache.axis2.handlers.AbstractHandler;
+import org.apache.axis2.engine.AxisEngine;
+import org.apache.axis2.transport.TransportSender;
+import org.apache.axis2.transport.OutTransportInfo;
+import org.apache.axis2.description.TransportOutDescription;
+import org.apache.axis2.description.TransportInDescription;
+import org.apache.axis2.description.WSDL2Constants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.axiom.om.util.UUIDGenerator;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.util.Map;
+import java.util.Set;
+
+public abstract class AbstractTransportSender extends AbstractHandler implements TransportSender {
+
+ /** the reference to the actual commons logger to be used for log messages */
+ protected Log log = null;
+
+ /** the axis2 configuration context */
+ protected ConfigurationContext cfgCtx = null;
+ /** transport in description */
+ private TransportInDescription transportIn = null;
+ /** transport out description */
+ private TransportOutDescription transportOut = null;
+ /** JMX support */
+ private TransportMBeanSupport mbeanSupport;
+ /** Metrics collector for the sender */
+ protected MetricsCollector metrics = new MetricsCollector();
+ /** state of the listener */
+ private int state = BaseConstants.STOPPED;
+
+ /**
+ * A constructor that makes subclasses pick up the correct logger
+ */
+ protected AbstractTransportSender() {
+ log = LogFactory.getLog(this.getClass());
+ }
+
+ /**
+ * Initialize the generic transport sender.
+ *
+ * @param cfgCtx the axis configuration context
+ * @param transportOut the transport-out description
+ * @throws AxisFault on error
+ */
+ public void init(ConfigurationContext cfgCtx, TransportOutDescription transportOut)
+ throws AxisFault {
+ this.cfgCtx = cfgCtx;
+ this.transportOut = transportOut;
+ this.transportIn = cfgCtx.getAxisConfiguration().getTransportIn(getTransportName());
+ this.state = BaseConstants.STARTED;
+
+ // register with JMX
+ mbeanSupport = new TransportMBeanSupport(this, getTransportName());
+ mbeanSupport.register();
+ log.info(getTransportName().toUpperCase() + " Sender started");
+ }
+
+ public void stop() {
+ if (state != BaseConstants.STARTED) return;
+ state = BaseConstants.STOPPED;
+ mbeanSupport.unregister();
+ log.info(getTransportName().toUpperCase() + " Sender Shutdown");
+ }
+
+ public void cleanup(MessageContext msgContext) throws AxisFault {}
+
+ public abstract void sendMessage(MessageContext msgCtx, String targetEPR,
+ OutTransportInfo outTransportInfo) throws AxisFault;
+
+ public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
+
+ // is there a transport url which may be different to the WS-A To but has higher precedence
+ String targetAddress = (String) msgContext.getProperty(
+ Constants.Configuration.TRANSPORT_URL);
+
+ if (targetAddress != null) {
+ sendMessage(msgContext, targetAddress, null);
+ } else if (msgContext.getTo() != null && !msgContext.getTo().hasAnonymousAddress()) {
+ targetAddress = msgContext.getTo().getAddress();
+
+ if (!msgContext.getTo().hasNoneAddress()) {
+ sendMessage(msgContext, targetAddress, null);
+ } else {
+ //Don't send the message.
+ return InvocationResponse.CONTINUE;
+ }
+ } else if (msgContext.isServerSide()) {
+ // get the out transport info for server side when target EPR is unknown
+ sendMessage(msgContext, null,
+ (OutTransportInfo) msgContext.getProperty(Constants.OUT_TRANSPORT_INFO));
+ }
+
+ return InvocationResponse.CONTINUE;
+ }
+
+ /**
+ * Process a new incoming message (Response) through the axis engine
+ * @param msgCtx the axis MessageContext
+ * @param trpHeaders the map containing transport level message headers
+ * @param soapAction the optional soap action or null
+ * @param contentType the optional content-type for the message
+ */
+ public void handleIncomingMessage(
+ MessageContext msgCtx, Map trpHeaders,
+ String soapAction, String contentType) {
+
+ // set the soapaction if one is available via a transport header
+ if (soapAction != null) {
+ msgCtx.setSoapAction(soapAction);
+ }
+
+ // set the transport headers to the message context
+ msgCtx.setProperty(MessageContext.TRANSPORT_HEADERS, trpHeaders);
+
+ // send the message context through the axis engine
+ try {
+ try {
+ AxisEngine.receive(msgCtx);
+ } catch (AxisFault e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Error receiving message", e);
+ }
+ if (msgCtx.isServerSide()) {
+ AxisEngine.sendFault(MessageContextBuilder.createFaultMessageContext(msgCtx, e));
+ }
+ }
+ } catch (AxisFault axisFault) {
+ logException("Error processing response message", axisFault);
+ }
+ }
+
+ /**
+ * Create a new axis MessageContext for an incoming response message
+ * through this transport, for the given outgoing message
+ *
+ * @param outMsgCtx the outgoing message
+ * @return the newly created message context
+ */
+ public MessageContext createResponseMessageContext(MessageContext outMsgCtx) {
+
+ MessageContext responseMsgCtx = null;
+ try {
+ responseMsgCtx = outMsgCtx.getOperationContext().
+ getMessageContext(WSDL2Constants.MESSAGE_LABEL_IN);
+ } catch (AxisFault af) {
+ log.error("Error getting IN message context from the operation context", af);
+ }
+
+ if (responseMsgCtx == null) {
+ responseMsgCtx = new MessageContext();
+ responseMsgCtx.setOperationContext(outMsgCtx.getOperationContext());
+ }
+
+ responseMsgCtx.setIncomingTransportName(getTransportName());
+ responseMsgCtx.setTransportOut(transportOut);
+ responseMsgCtx.setTransportIn(transportIn);
+
+ responseMsgCtx.setMessageID(UUIDGenerator.getUUID());
+
+ responseMsgCtx.setDoingREST(outMsgCtx.isDoingREST());
+ responseMsgCtx.setProperty(
+ MessageContext.TRANSPORT_IN, outMsgCtx.getProperty(MessageContext.TRANSPORT_IN));
+ responseMsgCtx.setAxisMessage(outMsgCtx.getOperationContext().getAxisOperation().
+ getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE));
+ responseMsgCtx.setTo(null);
+ //msgCtx.setProperty(MessageContext.TRANSPORT_NON_BLOCKING, isNonBlocking);
+
+
+ // are these relevant?
+ //msgCtx.setServiceGroupContextId(UUIDGenerator.getUUID());
+ // this is required to support Sandesha 2
+ //msgContext.setProperty(RequestResponseTransport.TRANSPORT_CONTROL,
+ // new HttpCoreRequestResponseTransport(msgContext));
+
+ return responseMsgCtx;
+ }
+
+ /**
+ * Should the transport sender wait for a synchronous response to be received?
+ * @param msgCtx the outgoing message context
+ * @return true if a sync response is expected
+ */
+ protected boolean waitForSynchronousResponse(MessageContext msgCtx) {
+ return
+ msgCtx.getOperationContext() != null &&
+ WSDL2Constants.MEP_URI_OUT_IN.equals(
+ msgCtx.getOperationContext().getAxisOperation().getMessageExchangePattern());
+ }
+
+ public String getTransportName() {
+ return transportOut.getName();
+ }
+
+ protected void handleException(String msg, Exception e) throws AxisFault {
+ log.error(msg, e);
+ throw new AxisFault(msg, e);
+ }
+
+ protected void handleException(String msg) throws AxisFault {
+ log.error(msg);
+ throw new AxisFault(msg);
+ }
+
+ protected void logException(String msg, Exception e) {
+ log.error(msg, e);
+ }
+
+ //--- jmx/management methods ---
+ public void pause() throws AxisFault {
+ if (state != BaseConstants.STARTED) return;
+ state = BaseConstants.PAUSED;
+ log.info("Sender paused");
+ }
+
+ public void resume() throws AxisFault {
+ if (state != BaseConstants.PAUSED) return;
+ state = BaseConstants.STARTED;
+ log.info("Sender resumed");
+ }
+
+ public void maintenenceShutdown(long millis) throws AxisFault {
+ if (state != BaseConstants.STARTED) return;
+ long start = System.currentTimeMillis();
+ stop();
+ state = BaseConstants.STOPPED;
+ log.info("Sender shutdown in : " + (System.currentTimeMillis() - start) / 1000 + "s");
+ }
+
+ /**
+ * Returns the number of active threads processing messages
+ * @return number of active threads processing messages
+ */
+ public int getActiveThreadCount() {
+ return 0;
+ }
+
+ /**
+ * Return the number of requests queued in the thread pool
+ * @return queue size
+ */
+ public int getQueueSize() {
+ return 0;
+ }
+
+ // -- jmx/management methods--
+ public long getMessagesReceived() {
+ if (metrics != null) {
+ return metrics.getMessagesReceived();
+ }
+ return -1;
+ }
+
+ public long getFaultsReceiving() {
+ if (metrics != null) {
+ return metrics.getFaultsReceiving();
+ }
+ return -1;
+ }
+
+ public long getBytesReceived() {
+ if (metrics != null) {
+ return metrics.getBytesReceived();
+ }
+ return -1;
+ }
+
+ public long getMessagesSent() {
+ if (metrics != null) {
+ return metrics.getMessagesSent();
+ }
+ return -1;
+ }
+
+ public long getFaultsSending() {
+ if (metrics != null) {
+ return metrics.getFaultsSending();
+ }
+ return -1;
+ }
+
+ public long getBytesSent() {
+ if (metrics != null) {
+ return metrics.getBytesSent();
+ }
+ return -1;
+ }
+
+ public long getTimeoutsReceiving() {
+ if (metrics != null) {
+ return metrics.getTimeoutsReceiving();
+ }
+ return -1;
+ }
+
+ public long getTimeoutsSending() {
+ if (metrics != null) {
+ return metrics.getTimeoutsSending();
+ }
+ return -1;
+ }
+
+ public long getMinSizeReceived() {
+ if (metrics != null) {
+ return metrics.getMinSizeReceived();
+ }
+ return -1;
+ }
+
+ public long getMaxSizeReceived() {
+ if (metrics != null) {
+ return metrics.getMaxSizeReceived();
+ }
+ return -1;
+ }
+
+ public double getAvgSizeReceived() {
+ if (metrics != null) {
+ return metrics.getAvgSizeReceived();
+ }
+ return -1;
+ }
+
+ public long getMinSizeSent() {
+ if (metrics != null) {
+ return metrics.getMinSizeSent();
+ }
+ return -1;
+ }
+
+ public long getMaxSizeSent() {
+ if (metrics != null) {
+ return metrics.getMaxSizeSent();
+ }
+ return -1;
+ }
+
+ public double getAvgSizeSent() {
+ if (metrics != null) {
+ return metrics.getAvgSizeSent();
+ }
+ return -1;
+ }
+
+ public Map getResponseCodeTable() {
+ if (metrics != null) {
+ return metrics.getResponseCodeTable();
+ }
+ return null;
+ }
+
+ public void resetStatistics() {
+ if (metrics != null) {
+ metrics.reset();
+ }
+ }
+
+ public long getLastResetTime() {
+ if (metrics != null) {
+ return metrics.getLastResetTime();
+ }
+ return -1;
+ }
+
+ public long getMetricsWindow() {
+ if (metrics != null) {
+ return System.currentTimeMillis() - metrics.getLastResetTime();
+ }
+ return -1;
+ }
+
+ private void registerMBean(MBeanServer mbs, Object mbeanInstance, String objectName) {
+ try {
+ ObjectName name = new ObjectName(objectName);
+ Set set = mbs.queryNames(name, null);
+ if (set != null && set.isEmpty()) {
+ mbs.registerMBean(mbeanInstance, name);
+ } else {
+ mbs.unregisterMBean(name);
+ mbs.registerMBean(mbeanInstance, name);
+ }
+ } catch (Exception e) {
+ log.warn("Error registering a MBean with objectname ' " + objectName +
+ " ' for JMX management", e);
+ }
+ }
+
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseConstants.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseConstants.java
new file mode 100644
index 0000000..fb7a825
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseConstants.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+
+import javax.xml.namespace.QName;
+
+public class BaseConstants {
+ // -- status of a transport --
+ public final static int STOPPED = 0;
+ public final static int STARTED = 1;
+ public final static int PAUSED = 2;
+
+ /**
+ * A message property specifying the SOAP Action
+ */
+ public static final String SOAPACTION = "SOAPAction";
+ /**
+ * A message property specifying the content type
+ */
+ public static final String CONTENT_TYPE = "Content-Type";
+ /**
+ * A message context property indicating "TRUE", if a transport or the message builder
+ * has information that the current message is a fault (e.g. SOAP faults, non-HTTP 2xx, etc)
+ */
+ public static final String FAULT_MESSAGE = "FAULT_MESSAGE";
+ /**
+ * content type identifier for multipart / MTOM messages
+ */
+ public static final String MULTIPART_RELATED = "multipart/related";
+ /**
+ * character set marker to identify charset from a Content-Type string
+ */
+ public static final String CHARSET_PARAM = "; charset=";
+ /**
+ * The property specifying an optional message level metrics collector
+ */
+ public static final String METRICS_COLLECTOR = "METRICS_COLLECTOR";
+
+ //------------------------------------ defaults ------------------------------------
+ /**
+ * The default operation name to be used for non SOAP/XML messages
+ * if the operation cannot be determined
+ */
+ public static final QName DEFAULT_OPERATION = new QName("urn:mediate");
+ /**
+ * The name of the element which wraps binary content into a SOAP envelope
+ */
+
+ // This has to match org.apache.synapse.util.PayloadHelper
+ // at some future point this can be merged into Axiom as a common base
+ public final static String AXIOMPAYLOADNS = "http://ws.apache.org/commons/ns/payload";
+
+
+ public static final QName DEFAULT_BINARY_WRAPPER =
+ new QName(AXIOMPAYLOADNS, "binary");
+ /**
+ * The name of the element which wraps plain text content into a SOAP envelope
+ */
+ public static final QName DEFAULT_TEXT_WRAPPER =
+ new QName(AXIOMPAYLOADNS, "text");
+
+ //-------------------------- services.xml parameters --------------------------------
+ /**
+ * The Parameter name indicating the operation to dispatch non SOAP/XML messages
+ */
+ public static final String OPERATION_PARAM = "Operation";
+ /**
+ * The Parameter name indicating the wrapper element for non SOAP/XML messages
+ */
+ public static final String WRAPPER_PARAM = "Wrapper";
+ /**
+ * the parameter in the services.xml that specifies the poll interval for a service
+ */
+ public static final String TRANSPORT_POLL_INTERVAL = "transport.PollInterval";
+ /**
+ * Could polling take place in parallel, i.e. starting at fixed intervals?
+ */
+ public static final String TRANSPORT_POLL_IN_PARALLEL = "transport.ConcurrentPollingAllowed";
+ /**
+ * The default poll interval in milliseconds.
+ */
+ public static final int DEFAULT_POLL_INTERVAL = 5 * 60 * 1000; // 5 mins by default
+
+ public static final String CALLBACK_TABLE = "callbackTable";
+ public static final String HEADER_IN_REPLY_TO = "In-Reply-To";
+
+ // this is an property required by axis2
+ // FIXME: where is this required in Axis2?
+ public final static String MAIL_CONTENT_TYPE = "mail.contenttype";
+
+ /** Service transaction level - non-transactional */
+ public static final int TRANSACTION_NONE = 0;
+ /** Service transaction level - use non-JTA (i.e. local) transactions */
+ public static final int TRANSACTION_LOCAL = 1;
+ /** Service transaction level - use JTA transactions */
+ public static final int TRANSACTION_JTA = 2;
+ /** Service transaction level - non-transactional */
+ public static final String STR_TRANSACTION_NONE = "none";
+ /** Service transaction level - use non-JTA (i.e. local) transactions */
+ public static final String STR_TRANSACTION_LOCAL = "local";
+ /** Service transaction level - use JTA transactions */
+ public static final String STR_TRANSACTION_JTA = "jta";
+
+ /** The Parameter name indicating the transactionality of a service */
+ public static final String PARAM_TRANSACTIONALITY = "transport.Transactionality";
+ /** Parameter name indicating the JNDI name to get a UserTransaction from JNDI */
+ public static final String PARAM_USER_TXN_JNDI_NAME = "transport.UserTxnJNDIName";
+ /** Parameter that indicates if a UserTransaction reference could be cached - default yes */
+ public static final String PARAM_CACHE_USER_TXN = "transport.CacheUserTxn";
+
+ /** The UserTransaction associated with this message */
+ public static final String USER_TRANSACTION = "UserTransaction";
+ /** A message level property indicating a request to rollback the transaction associated with the message */
+ public static final String SET_ROLLBACK_ONLY = "SET_ROLLBACK_ONLY";
+ /** A message level property indicating a commit is required after the next immidiate send over a transport */
+ public static final String JTA_COMMIT_AFTER_SEND = "JTA_COMMIT_AFTER_SEND";
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseTransportException.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseTransportException.java
new file mode 100644
index 0000000..b69dc9e
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseTransportException.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.axis2.transport.base;
+
+public class BaseTransportException extends RuntimeException {
+
+ BaseTransportException() {
+ super();
+ }
+
+ public BaseTransportException(String msg) {
+ super(msg);
+ }
+
+ public BaseTransportException(String msg, Exception e) {
+ super(msg, e);
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseUtils.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseUtils.java
new file mode 100644
index 0000000..6c0a7af
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/BaseUtils.java
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.impl.builder.StAXBuilder;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.Constants;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.format.BinaryFormatter;
+import org.apache.axis2.format.PlainTextFormatter;
+import org.apache.axis2.transport.MessageFormatter;
+import org.apache.axis2.transport.TransportUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+public class BaseUtils {
+
+ private static final Log log = LogFactory.getLog(BaseUtils.class);
+
+ /**
+ * Return a QName from the String passed in of the form {ns}element
+ * @param obj a QName or a String containing a QName in {ns}element form
+ * @return a corresponding QName object
+ */
+ public static QName getQNameFromString(Object obj) {
+ String value;
+ if (obj instanceof QName) {
+ return (QName) obj;
+ } else {
+ value = obj.toString();
+ }
+ int open = value.indexOf('{');
+ int close = value.indexOf('}');
+ if (close > open && open > -1 && value.length() > close) {
+ return new QName(value.substring(open+1, close-open), value.substring(close+1));
+ } else {
+ return new QName(value);
+ }
+ }
+
+ /**
+ * Marks the given service as faulty with the given comment
+ *
+ * @param serviceName service name
+ * @param msg comment for being faulty
+ * @param axisCfg configuration context
+ */
+ public static void markServiceAsFaulty(String serviceName, String msg,
+ AxisConfiguration axisCfg) {
+ if (serviceName != null) {
+ try {
+ AxisService service = axisCfg.getService(serviceName);
+ axisCfg.getFaultyServices().put(service.getName(), msg);
+
+ } catch (AxisFault axisFault) {
+ log.warn("Error marking service : " + serviceName + " as faulty", axisFault);
+ }
+ }
+ }
+
+ /**
+ * Create a SOAP envelope using SOAP 1.1 or 1.2 depending on the namespace
+ * @param in InputStream for the payload
+ * @param namespace the SOAP namespace
+ * @return the SOAP envelope for the correct version
+ * @throws javax.xml.stream.XMLStreamException on error
+ */
+ public static SOAPEnvelope getEnvelope(InputStream in, String namespace) throws XMLStreamException {
+
+ try {
+ in.reset();
+ } catch (IOException ignore) {}
+ XMLStreamReader xmlreader =
+ StAXUtils.createXMLStreamReader(in, MessageContext.DEFAULT_CHAR_SET_ENCODING);
+ StAXBuilder builder = new StAXSOAPModelBuilder(xmlreader, namespace);
+ return (SOAPEnvelope) builder.getDocumentElement();
+ }
+
+ /**
+ * Get the OMOutput format for the given message
+ * @param msgContext the axis message context
+ * @return the OMOutput format to be used
+ */
+ public static OMOutputFormat getOMOutputFormat(MessageContext msgContext) {
+
+ OMOutputFormat format = new OMOutputFormat();
+ msgContext.setDoingMTOM(TransportUtils.doWriteMTOM(msgContext));
+ msgContext.setDoingSwA(TransportUtils.doWriteSwA(msgContext));
+ msgContext.setDoingREST(TransportUtils.isDoingREST(msgContext));
+ format.setSOAP11(msgContext.isSOAP11());
+ format.setDoOptimize(msgContext.isDoingMTOM());
+ format.setDoingSWA(msgContext.isDoingSwA());
+
+ format.setCharSetEncoding(TransportUtils.getCharSetEncoding(msgContext));
+ Object mimeBoundaryProperty = msgContext.getProperty(Constants.Configuration.MIME_BOUNDARY);
+ if (mimeBoundaryProperty != null) {
+ format.setMimeBoundary((String) mimeBoundaryProperty);
+ }
+ return format;
+ }
+
+ /**
+ * Get the MessageFormatter for the given message.
+ * @param msgContext the axis message context
+ * @return the MessageFormatter to be used
+ */
+ public static MessageFormatter getMessageFormatter(MessageContext msgContext) {
+ // check the first element of the SOAP body, do we have content wrapped using the
+ // default wrapper elements for binary (BaseConstants.DEFAULT_BINARY_WRAPPER) or
+ // text (BaseConstants.DEFAULT_TEXT_WRAPPER) ? If so, select the appropriate
+ // message formatter directly ...
+ OMElement firstChild = msgContext.getEnvelope().getBody().getFirstElement();
+ if (firstChild != null) {
+ if (BaseConstants.DEFAULT_BINARY_WRAPPER.equals(firstChild.getQName())) {
+ return new BinaryFormatter();
+ } else if (BaseConstants.DEFAULT_TEXT_WRAPPER.equals(firstChild.getQName())) {
+ return new PlainTextFormatter();
+ }
+ }
+
+ // ... otherwise, let Axis choose the right message formatter:
+ try {
+ return TransportUtils.getMessageFormatter(msgContext);
+ } catch (AxisFault axisFault) {
+ throw new BaseTransportException("Unable to get the message formatter to use");
+ }
+ }
+
+ protected static void handleException(String s) {
+ log.error(s);
+ throw new BaseTransportException(s);
+ }
+
+ protected static void handleException(String s, Exception e) {
+ log.error(s, e);
+ throw new BaseTransportException(s, e);
+ }
+
+ /**
+ * Utility method to check if a string is null or empty
+ * @param str the string to check
+ * @return true if the string is null or empty
+ */
+ public static boolean isBlank(String str) {
+ if (str == null || str.length() == 0) {
+ return true;
+ }
+ for (int i = 0; i < str.length(); i++) {
+ if (!Character.isWhitespace(str.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isUsingTransport(AxisService service, String transportName) {
+ boolean process = service.isEnableAllTransports();
+ if (process) {
+ return true;
+
+ } else {
+ List transports = service.getExposedTransports();
+ for (Object transport : transports) {
+ if (transportName.equals(transport)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Extract the properties from an endpoint reference.
+ *
+ * @param url an endpoint reference
+ * @return the extracted properties
+ */
+ public static Hashtable<String,String> getEPRProperties(String url) {
+ Hashtable<String,String> h = new Hashtable<String,String>();
+ int propPos = url.indexOf("?");
+ if (propPos != -1) {
+ StringTokenizer st = new StringTokenizer(url.substring(propPos + 1), "&");
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ int sep = token.indexOf("=");
+ if (sep != -1) {
+ h.put(token.substring(0, sep), token.substring(sep + 1));
+ } else {
+ // ignore, what else can we do?
+ }
+ }
+ }
+ return h;
+ }
+
+ /**
+ * Loads the properties from a given property file path
+ *
+ * @param filePath Path of the property file
+ * @return Properties loaded from given file
+ */
+ public static Properties loadProperties(String filePath) {
+
+ Properties properties = new Properties();
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Loading a file '" + filePath + "' from classpath");
+ }
+
+ InputStream in = cl.getResourceAsStream(filePath);
+ if (in == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unable to load file '" + filePath + "'");
+ }
+
+ filePath = "conf" +
+ File.separatorChar + filePath;
+ if (log.isDebugEnabled()) {
+ log.debug("Loading a file '" + filePath + "' from classpath");
+ }
+
+ in = cl.getResourceAsStream(filePath);
+ if (in == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unable to load file ' " + filePath + " '");
+ }
+ }
+ }
+ if (in != null) {
+ try {
+ properties.load(in);
+ } catch (IOException e) {
+ String msg = "Error loading properties from a file at :" + filePath;
+ log.error(msg, e);
+ throw new BaseTransportException(msg, e);
+ }
+ }
+ return properties;
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ManagementSupport.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ManagementSupport.java
new file mode 100644
index 0000000..4b28ca5
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ManagementSupport.java
@@ -0,0 +1,50 @@
+package org.apache.axis2.transport.base;
+
+import org.apache.axis2.AxisFault;
+import java.util.Map;
+
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+public interface ManagementSupport {
+ public void pause() throws AxisFault;
+ public void resume() throws AxisFault;
+ void maintenenceShutdown(long millis) throws AxisFault;
+ public int getActiveThreadCount();
+ public int getQueueSize();
+
+ public long getMessagesReceived();
+ public long getFaultsReceiving();
+ public long getTimeoutsReceiving();
+ public long getMessagesSent();
+ public long getFaultsSending();
+ public long getTimeoutsSending();
+ public long getBytesReceived();
+ public long getBytesSent();
+ public long getMinSizeReceived();
+ public long getMaxSizeReceived();
+ public double getAvgSizeReceived();
+ public long getMinSizeSent();
+ public long getMaxSizeSent();
+ public double getAvgSizeSent();
+ public Map getResponseCodeTable();
+
+ public void resetStatistics();
+ public long getLastResetTime();
+ public long getMetricsWindow();
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/MessageLevelMetricsCollector.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/MessageLevelMetricsCollector.java
new file mode 100644
index 0000000..9d2f94c
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/MessageLevelMetricsCollector.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+public interface MessageLevelMetricsCollector {
+
+ public void incrementMessagesReceived();
+
+ public void incrementFaultsReceiving(int errorCode);
+
+ public void incrementTimeoutsReceiving();
+
+ public void incrementBytesReceived(long size);
+
+ public void incrementMessagesSent();
+
+ public void incrementFaultsSending(int errorCode);
+
+ public void incrementTimeoutsSending();
+
+ public void incrementBytesSent(long size);
+
+ public void notifyReceivedMessageSize(long size);
+
+ public void notifySentMessageSize(long size);
+
+ public void reportReceivingFault(int errorCode);
+
+ public void reportSendingFault(int errorCode);
+
+ public void reportResponseCode(int respCode);
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/MetricsCollector.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/MetricsCollector.java
new file mode 100644
index 0000000..4938afb
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/MetricsCollector.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+import org.apache.axis2.context.MessageContext;
+
+import java.util.Map;
+import java.util.Collections;
+import java.util.HashMap;
+
+/**
+ * Collects metrics related to a transport that has metrics support enabled
+ */
+public class MetricsCollector {
+
+ public static final int LEVEL_NONE = 0;
+ public static final int LEVEL_TRANSPORT = 1;
+ public static final int LEVEL_FULL = 2;
+ private static final Long ONE = (long) 1;
+
+ /** By default, full metrics collection is enabled */
+ private int level = LEVEL_FULL;
+
+ private long messagesReceived;
+ private long faultsReceiving;
+ private long timeoutsReceiving;
+ private long bytesReceived;
+ private long minSizeReceived;
+ private long maxSizeReceived;
+ private double avgSizeReceived;
+
+ private long messagesSent;
+ private long faultsSending;
+ private long timeoutsSending;
+ private long bytesSent;
+ private long minSizeSent;
+ private long maxSizeSent;
+ private double avgSizeSent;
+
+ private final Map<Integer, Long> responseCodeTable =
+ Collections.synchronizedMap(new HashMap<Integer, Long>());
+
+ private long lastResetTime = System.currentTimeMillis();
+
+ public void reset() {
+ messagesReceived = 0;
+ faultsReceiving = 0;
+ timeoutsReceiving = 0;
+ bytesReceived = 0;
+ minSizeReceived = 0;
+ maxSizeReceived = 0;
+ avgSizeReceived = 0;
+
+ messagesSent = 0;
+ faultsSending = 0;
+ timeoutsSending = 0;
+ bytesSent = 0;
+ minSizeSent = 0;
+ maxSizeSent = 0;
+ avgSizeSent = 0;
+
+ responseCodeTable.clear();
+ lastResetTime = System.currentTimeMillis();
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public void setLevel(int level) {
+ this.level = level;
+ }
+
+ public long getLastResetTime() {
+ return lastResetTime;
+ }
+
+ public long getMessagesReceived() {
+ return messagesReceived;
+ }
+
+ public long getFaultsReceiving() {
+ return faultsReceiving;
+ }
+
+ public long getTimeoutsReceiving() {
+ return timeoutsReceiving;
+ }
+
+ public long getBytesReceived() {
+ return bytesReceived;
+ }
+
+ public long getMessagesSent() {
+ return messagesSent;
+ }
+
+ public long getFaultsSending() {
+ return faultsSending;
+ }
+
+ public long getTimeoutsSending() {
+ return timeoutsSending;
+ }
+
+ public long getBytesSent() {
+ return bytesSent;
+ }
+
+ public long getMinSizeReceived() {
+ return minSizeReceived;
+ }
+
+ public long getMaxSizeReceived() {
+ return maxSizeReceived;
+ }
+
+ public long getMinSizeSent() {
+ return minSizeSent;
+ }
+
+ public long getMaxSizeSent() {
+ return maxSizeSent;
+ }
+
+ public double getAvgSizeReceived() {
+ return avgSizeReceived;
+ }
+
+ public double getAvgSizeSent() {
+ return avgSizeSent;
+ }
+
+ public Map<Integer, Long> getResponseCodeTable() {
+ return responseCodeTable;
+ }
+
+ public synchronized void incrementMessagesReceived() {
+ messagesReceived++;
+ }
+
+ public synchronized void incrementFaultsReceiving() {
+ faultsReceiving++;
+ }
+
+ public synchronized void incrementTimeoutsReceiving() {
+ timeoutsReceiving++;
+ }
+
+ public synchronized void incrementBytesReceived(long size) {
+ bytesReceived += size;
+ }
+
+ public synchronized void incrementMessagesSent() {
+ messagesSent++;
+ }
+
+ public synchronized void incrementFaultsSending() {
+ faultsSending++;
+ }
+
+ public synchronized void incrementTimeoutsSending() {
+ timeoutsSending++;
+ }
+
+ public synchronized void incrementBytesSent(long size) {
+ bytesSent += size;
+ }
+
+ public synchronized void notifyReceivedMessageSize(long size) {
+ if (minSizeReceived == 0 || size < minSizeReceived) {
+ minSizeReceived = size;
+ }
+ if (size > maxSizeReceived) {
+ maxSizeReceived = size;
+ }
+ avgSizeReceived = (avgSizeReceived == 0 ? size : (avgSizeReceived + size) / 2);
+ }
+
+ public synchronized void notifySentMessageSize(long size) {
+ if (minSizeSent == 0 || size < minSizeSent) {
+ minSizeSent = size;
+ }
+ if (size > maxSizeSent) {
+ maxSizeSent = size;
+ }
+ avgSizeSent = (avgSizeSent == 0 ? size : (avgSizeSent + size) / 2);
+ }
+
+ public void reportResponseCode(int respCode) {
+ synchronized(responseCodeTable) {
+ Object o = responseCodeTable.get(respCode);
+ if (o == null) {
+ responseCodeTable.put(respCode, ONE);
+ } else {
+ responseCodeTable.put(respCode, (Long) o + 1);
+ }
+ }
+ }
+
+ // --- enhanced methods ---
+ private MessageLevelMetricsCollector getMsgLevelMetrics(MessageContext mc) {
+ if (mc != null && level == LEVEL_FULL) {
+ return (MessageLevelMetricsCollector) mc.getProperty(BaseConstants.METRICS_COLLECTOR);
+ }
+ return null;
+ }
+
+ public void incrementMessagesReceived(MessageContext mc) {
+ incrementMessagesReceived();
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.incrementMessagesReceived();
+ }
+ }
+
+ public void incrementFaultsReceiving(int errorCode, MessageContext mc) {
+ incrementFaultsReceiving();
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.incrementFaultsReceiving(errorCode);
+ }
+ }
+
+ public void incrementTimeoutsReceiving(MessageContext mc) {
+ incrementTimeoutsReceiving();
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.incrementTimeoutsReceiving();
+ }
+ }
+
+ public void incrementBytesReceived(MessageContext mc, long size) {
+ incrementBytesReceived(size);
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.incrementBytesReceived(size);
+ }
+ }
+
+ public void incrementMessagesSent(MessageContext mc) {
+ incrementMessagesSent();
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.incrementMessagesSent();
+ }
+ }
+
+ public void incrementFaultsSending(int errorCode, MessageContext mc) {
+ incrementFaultsSending();
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.incrementFaultsSending(errorCode);
+ }
+ }
+
+ public void incrementTimeoutsSending(MessageContext mc) {
+ incrementTimeoutsSending();
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.incrementTimeoutsSending();
+ }
+ }
+
+ public void incrementBytesSent(MessageContext mc, long size) {
+ incrementBytesSent(size);
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.incrementBytesSent(size);
+ }
+ }
+
+ public void notifyReceivedMessageSize(MessageContext mc, long size) {
+ notifyReceivedMessageSize(size);
+
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.notifyReceivedMessageSize(size);
+ }
+ }
+
+ public void notifySentMessageSize(MessageContext mc, long size) {
+ notifySentMessageSize(size);
+
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.notifySentMessageSize(size);
+ }
+ }
+
+ public void reportResponseCode(MessageContext mc, int respCode) {
+ reportResponseCode(respCode);
+
+ MessageLevelMetricsCollector m = getMsgLevelMetrics(mc);
+ if (m != null) {
+ m.reportResponseCode(respCode);
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ParamUtils.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ParamUtils.java
new file mode 100644
index 0000000..77e6815
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ParamUtils.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.description.ParameterInclude;
+import org.apache.axis2.description.TransportInDescription;
+import org.apache.axis2.description.TransportOutDescription;
+import org.apache.axis2.util.JavaUtils;
+
+/**
+ * Utility class with methods to manipulate service or transport parameters.
+ */
+public class ParamUtils {
+ private ParamUtils() {}
+
+ public static String getRequiredParam(ParameterInclude paramInclude, String paramName) throws AxisFault {
+ Parameter param = paramInclude.getParameter(paramName);
+ if (param != null && param.getValue() != null && param.getValue() instanceof String) {
+ return (String) param.getValue();
+ } else {
+ throw new AxisFault("Cannot find parameter '" + paramName + "' for "
+ + getDescriptionFor(paramInclude));
+ }
+ }
+
+ public static String getOptionalParam(ParameterInclude paramInclude, String paramName) throws AxisFault {
+ Parameter param = paramInclude.getParameter(paramName);
+ if (param != null && param.getValue() != null && param.getValue() instanceof String) {
+ return (String) param.getValue();
+ } else {
+ return null;
+ }
+ }
+
+ public static Integer getOptionalParamInt(ParameterInclude paramInclude, String paramName) throws AxisFault {
+ Parameter param = paramInclude.getParameter(paramName);
+ if (param == null || param.getValue() == null) {
+ return null;
+ } else {
+ Object paramValue = param.getValue();
+ if (paramValue instanceof Integer) {
+ return (Integer)paramValue;
+ } else if (paramValue instanceof String) {
+ try {
+ return Integer.valueOf((String)paramValue);
+ } catch (NumberFormatException ex) {
+ throw new AxisFault("Invalid value '" + paramValue + "' for parameter '" + paramName +
+ "' for " + getDescriptionFor(paramInclude));
+ }
+ } else {
+ throw new AxisFault("Invalid type for parameter '" + paramName + "' for " +
+ getDescriptionFor(paramInclude));
+ }
+ }
+ }
+
+ public static int getOptionalParamInt(ParameterInclude paramInclude, String paramName, int defaultValue) throws AxisFault {
+ Integer value = getOptionalParamInt(paramInclude, paramName);
+ return value == null ? defaultValue : value.intValue();
+ }
+
+ public static boolean getOptionalParamBoolean(ParameterInclude paramInclude, String paramName, boolean defaultValue) throws AxisFault {
+ Parameter param = paramInclude.getParameter(paramName);
+ return param == null ? defaultValue : JavaUtils.isTrueExplicitly(param.getValue(), defaultValue);
+ }
+
+ public static int getRequiredParamInt(ParameterInclude paramInclude, String paramName) throws AxisFault {
+ Integer value = getOptionalParamInt(paramInclude, paramName);
+ if (value == null) {
+ throw new AxisFault("Cannot find parameter '" + paramName +
+ "' for " + getDescriptionFor(paramInclude));
+ } else {
+ return value.intValue();
+ }
+ }
+
+ private static String getDescriptionFor(ParameterInclude paramInclude) {
+ if (paramInclude instanceof AxisService) {
+ return "service '" + ((AxisService)paramInclude).getName() + "'";
+ } else if (paramInclude instanceof TransportInDescription) {
+ return "transport receiver '" + ((TransportInDescription)paramInclude).getName() + "'";
+ } else if (paramInclude instanceof TransportOutDescription) {
+ return "transport sender '" + ((TransportOutDescription)paramInclude).getName() + "'";
+ } else {
+ return paramInclude.getClass().getName();
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ProtocolEndpoint.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ProtocolEndpoint.java
new file mode 100644
index 0000000..7dfaed4
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/ProtocolEndpoint.java
@@ -0,0 +1,116 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.description.ParameterInclude;
+import org.apache.axis2.description.WSDL2Constants;
+
+/**
+ * Describes a protocol specific endpoint. This might be a TCP/UDP port, a mail account,
+ * a JMS destination, etc. Typically, a protocol specific endpoint is mapped to a
+ * service.
+ */
+public abstract class ProtocolEndpoint {
+ private AbstractTransportListenerEx<?> listener;
+ /** Axis2 service */
+ private AxisService service;
+
+ // This is called only by AbstractTransportListenerEx and must have package access
+ void init(AbstractTransportListenerEx<?> listener, AxisService service) {
+ this.listener = listener;
+ this.service = service;
+ }
+
+ public final AbstractTransportListenerEx<?> getListener() {
+ return listener;
+ }
+
+ public final AxisService getService() {
+ return service;
+ }
+
+ public final String getServiceName() {
+ return service.getName();
+ }
+
+ /**
+ * Configure the endpoint based on the provided parameters.
+ * If no relevant parameters are found, the implementation should
+ * return <code>false</code>. An exception should only be thrown if there is an
+ * error or inconsistency in the parameters.
+ *
+ * @param params The source of the parameters to construct the
+ * poll table entry. If the parameters are defined on
+ * a service, this will be an {@link AxisService}
+ * instance.
+ * @return <code>true</code> if the parameters contained the required configuration
+ * information and the endpoint has been configured, <code>false</code> if
+ * the no configuration for the endpoint is present in the parameters
+ * @throws AxisFault if configuration information is present, but there is an
+ * error or inconsistency in the parameters
+ */
+ public abstract boolean loadConfiguration(ParameterInclude params) throws AxisFault;
+
+ /**
+ * Get the endpoint references for this protocol endpoint.
+ *
+ * @param ip The host name or IP address of the local host. The implementation should use
+ * this information instead of {@link java.net.InetAddress#getLocalHost()}.
+ * The value of this parameter may be <code>null</code>, in which case the
+ * implementation should use {@link org.apache.axis2.util.Utils#getIpAddress(
+ * org.apache.axis2.engine.AxisConfiguration)}.
+ * @return an array of endpoint references
+ * @throws AxisFault
+ *
+ * @see org.apache.axis2.transport.TransportListener#getEPRsForService(String, String)
+ */
+ public abstract EndpointReference[] getEndpointReferences(String ip) throws AxisFault;
+
+ public MessageContext createMessageContext() throws AxisFault {
+ MessageContext msgContext = listener.createMessageContext();
+
+ if (service != null) {
+ msgContext.setAxisService(service);
+
+ // find the operation for the message, or default to one
+ Parameter operationParam = service.getParameter(BaseConstants.OPERATION_PARAM);
+ QName operationQName = (
+ operationParam != null ?
+ BaseUtils.getQNameFromString(operationParam.getValue()) :
+ BaseConstants.DEFAULT_OPERATION);
+
+ AxisOperation operation = service.getOperation(operationQName);
+ if (operation != null) {
+ msgContext.setAxisOperation(operation);
+ msgContext.setAxisMessage(
+ operation.getMessage(WSDL2Constants.MESSAGE_LABEL_IN));
+ msgContext.setSoapAction("urn:" + operation.getName().getLocalPart());
+ }
+ }
+ return msgContext;
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/SynchronousCallback.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/SynchronousCallback.java
new file mode 100644
index 0000000..fd00cee
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/SynchronousCallback.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.
+ */
+package org.apache.axis2.transport.base;
+
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.context.OperationContext;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisMessage;
+import org.apache.axis2.wsdl.WSDLConstants;
+
+
+public class SynchronousCallback {
+
+ private MessageContext outMessageContext;
+ private MessageContext inMessageContext;
+
+ private boolean isComplete;
+
+ public SynchronousCallback(MessageContext outMessageContext) {
+ this.outMessageContext = outMessageContext;
+ this.isComplete = false;
+ }
+
+ public synchronized void setInMessageContext(MessageContext inMessageContext) throws AxisFault {
+
+ // if some other thread has access and complete then return without doing any thing.
+ // thread should have activate by the first message.
+ if (!isComplete) {
+ // this code is invoked only if the code use with axis2 at the client side
+ // when axis2 client receive messages it waits in the sending thread until the response comes.
+ // so this thread only notify the waiting thread and hence we need to build the message here.
+ inMessageContext.getEnvelope().build();
+ OperationContext operationContext = outMessageContext.getOperationContext();
+ MessageContext msgCtx =
+ operationContext.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+
+ if (msgCtx == null) {
+ // try to see whether there is a piggy back message context
+ if (outMessageContext.getProperty(org.apache.axis2.Constants.PIGGYBACK_MESSAGE) != null) {
+
+ msgCtx = (MessageContext) outMessageContext.getProperty(org.apache.axis2.Constants.PIGGYBACK_MESSAGE);
+ msgCtx.setTransportIn(inMessageContext.getTransportIn());
+ msgCtx.setTransportOut(inMessageContext.getTransportOut());
+ msgCtx.setServerSide(false);
+ msgCtx.setProperty(BaseConstants.MAIL_CONTENT_TYPE,
+ inMessageContext.getProperty(BaseConstants.MAIL_CONTENT_TYPE));
+ // FIXME: this class must not be transport dependent since it is used by AbstractTransportListener
+ msgCtx.setIncomingTransportName(org.apache.axis2.Constants.TRANSPORT_MAIL);
+ msgCtx.setEnvelope(inMessageContext.getEnvelope());
+
+ } else {
+ inMessageContext.setOperationContext(operationContext);
+ inMessageContext.setServiceContext(outMessageContext.getServiceContext());
+ if (!operationContext.isComplete()) {
+ operationContext.addMessageContext(inMessageContext);
+ }
+ AxisOperation axisOp = operationContext.getAxisOperation();
+ AxisMessage inMessage = axisOp.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+ inMessageContext.setAxisMessage(inMessage);
+ inMessageContext.setServerSide(false);
+ }
+
+ } else {
+ msgCtx.setOperationContext(operationContext);
+ msgCtx.setServiceContext(outMessageContext.getServiceContext());
+ AxisOperation axisOp = operationContext.getAxisOperation();
+ AxisMessage inMessage = axisOp.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+ msgCtx.setAxisMessage(inMessage);
+ msgCtx.setTransportIn(inMessageContext.getTransportIn());
+ msgCtx.setTransportOut(inMessageContext.getTransportOut());
+ msgCtx.setServerSide(false);
+ msgCtx.setProperty(BaseConstants.MAIL_CONTENT_TYPE,
+ inMessageContext.getProperty(BaseConstants.MAIL_CONTENT_TYPE));
+ // FIXME: this class must not be transport dependent since it is used by AbstractTransportListener
+ msgCtx.setIncomingTransportName(org.apache.axis2.Constants.TRANSPORT_MAIL);
+ msgCtx.setEnvelope(inMessageContext.getEnvelope());
+
+ }
+ this.inMessageContext = inMessageContext;
+ isComplete = true;
+ this.notifyAll();
+ }
+
+ }
+
+
+ public boolean isComplete() {
+ return isComplete;
+ }
+
+ public void setComplete(boolean complete) {
+ isComplete = complete;
+ }
+
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportConfiguration.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportConfiguration.java
new file mode 100644
index 0000000..a9c3c44
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportConfiguration.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Properties;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ *
+ */
+public class TransportConfiguration {
+
+ // defaults
+ private static final int WORKERS_CORE_THREADS = 20;
+ private static final int WORKERS_MAX_THREADS = 100;
+ private static final int WORKER_KEEP_ALIVE = 5;
+ private static final int BLOCKING_QUEUE_LENGTH = -1;
+
+ // server listener
+ private static final String S_T_CORE = "snd_t_core";
+ private static final String S_T_MAX = "snd_t_max";
+ private static final String S_T_ALIVE = "snd_alive_sec";
+ private static final String S_T_QLEN = "snd_qlen";
+
+ // client sender
+ private static final String C_T_CORE = "lst_t_core";
+ private static final String C_T_MAX = "lst_t_max";
+ private static final String C_T_ALIVE = "lst_alive_sec";
+ private static final String C_T_QLEN = "lst_qlen";
+
+ private static final Log log = LogFactory.getLog(TransportConfiguration.class);
+ private static Map<String, TransportConfiguration> _configurations
+ = new HashMap<String, TransportConfiguration>();
+ private Properties props;
+
+ private TransportConfiguration(String transportName) {
+ try {
+ props = BaseUtils.loadProperties(transportName + ".properties");
+ } catch (Exception ignore) {}
+ }
+
+ public static TransportConfiguration getConfiguration(String transportName) {
+ if (_configurations.containsKey(transportName)) {
+ return _configurations.get(transportName);
+ } else {
+ TransportConfiguration config = new TransportConfiguration(transportName);
+ _configurations.put(transportName, config);
+ return config;
+ }
+ }
+
+ public int getServerCoreThreads() {
+ return getProperty(S_T_CORE, WORKERS_CORE_THREADS);
+ }
+
+ public int getServerMaxThreads() {
+ return getProperty(S_T_MAX, WORKERS_MAX_THREADS);
+ }
+
+ public int getServerKeepalive() {
+ return getProperty(S_T_ALIVE, WORKER_KEEP_ALIVE);
+ }
+
+ public int getServerQueueLen() {
+ return getProperty(S_T_QLEN, BLOCKING_QUEUE_LENGTH);
+ }
+
+ public int getClientCoreThreads() {
+ return getProperty(C_T_CORE, WORKERS_CORE_THREADS);
+ }
+
+ public int getClientMaxThreads() {
+ return getProperty(C_T_MAX, WORKERS_MAX_THREADS);
+ }
+
+ public int getClientKeepalive() {
+ return getProperty(C_T_ALIVE, WORKER_KEEP_ALIVE);
+ }
+
+ public int getClientQueueLen() {
+ return getProperty(C_T_QLEN, BLOCKING_QUEUE_LENGTH);
+ }
+
+ /**
+ * Get properties that tune nhttp transport. Preference to system properties
+ * @param name name of the system/config property
+ * @param def default value to return if the property is not set
+ * @return the value of the property to be used
+ */
+ public int getProperty(String name, int def) {
+ String val = System.getProperty(name);
+ if (val == null) {
+ val = props.getProperty(name);
+ }
+
+ if (val != null && Integer.valueOf(val) > 0) {
+ if (log.isDebugEnabled()) {
+ log.debug("Using transport tuning parameter : " + name + " = " + val);
+ }
+ return Integer.valueOf(val);
+ }
+ return def;
+ }
+
+ /**
+ * Get properties that tune nhttp transport. Preference to system properties
+ * @param name name of the system/config property
+ * @param def default value to return if the property is not set
+ * @return the value of the property to be used
+ */
+ public boolean getBooleanValue(String name, boolean def) {
+ String val = System.getProperty(name);
+ if (val == null) {
+ val = props.getProperty(name);
+ }
+
+ if (val != null && Boolean.parseBoolean(val)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Using transport tuning parameter : " + name);
+ }
+ return true;
+ }
+ return def;
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportListenerEndpointView.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportListenerEndpointView.java
new file mode 100644
index 0000000..2649291
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportListenerEndpointView.java
@@ -0,0 +1,61 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+package org.apache.axis2.transport.base;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.EndpointReference;
+
+public class TransportListenerEndpointView implements TransportListenerEndpointViewMBean {
+ private final AbstractTransportListener listener;
+ private final String serviceName;
+
+ public TransportListenerEndpointView(AbstractTransportListener listener, String serviceName) {
+ this.listener = listener;
+ this.serviceName = serviceName;
+ }
+
+ public String[] getAddresses() {
+ String hostname;
+ try {
+ hostname = InetAddress.getLocalHost().getHostName();
+ }
+ catch (UnknownHostException ex) {
+ hostname = "localhost";
+ }
+ EndpointReference[] epr;
+ try {
+ epr = listener.getEPRsForService(serviceName, hostname);
+ }
+ catch (AxisFault ex) {
+ return null;
+ }
+ if (epr == null) {
+ return null;
+ } else {
+ String[] result = new String[epr.length];
+ for (int i=0; i<epr.length; i++) {
+ result[i] = epr[i].getAddress();
+ }
+ return result;
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportListenerEndpointViewMBean.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportListenerEndpointViewMBean.java
new file mode 100644
index 0000000..64d97c8
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportListenerEndpointViewMBean.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.axis2.transport.base;
+
+public interface TransportListenerEndpointViewMBean {
+ String[] getAddresses();
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportMBeanSupport.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportMBeanSupport.java
new file mode 100644
index 0000000..773a18c
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportMBeanSupport.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.axis2.transport.TransportListener;
+import org.apache.axis2.transport.TransportSender;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Support class to register MBeans for transport listeners and senders.
+ * This class can be used by {@link TransportListener} and {@link TransportSender} classes
+ * to register the {@link TransportView} management bean. It takes care of registering
+ * the bean under a consistent name and makes sure that a JMX related error doesn't stop
+ * the transport from working: a failure to register the MBean will cause JMX support
+ * to be disabled.
+ */
+public class TransportMBeanSupport {
+ private static final Log log = LogFactory.getLog(TransportMBeanSupport.class);
+
+ private boolean enabled = true;
+ private boolean registered;
+ private MBeanServer mbs;
+ private ObjectName mbeanName;
+ private TransportView mbeanInstance;
+
+ private TransportMBeanSupport(String connectorName, TransportView mbeanInstance) {
+ try {
+ mbs = ManagementFactory.getPlatformMBeanServer();
+ } catch (SecurityException ex) {
+ log.warn("Unable to get the platform MBean server; JMX support disabled", ex);
+ enabled = false;
+ return;
+ }
+ String jmxAgentName = System.getProperty("jmx.agent.name");
+ if (jmxAgentName == null || "".equals(jmxAgentName)) {
+ jmxAgentName = "org.apache.axis2";
+ }
+ String mbeanNameString = jmxAgentName + ":Type=Transport,ConnectorName=" + connectorName;
+ try {
+ mbeanName = ObjectName.getInstance(mbeanNameString);
+ } catch (MalformedObjectNameException ex) {
+ log.warn("Unable to create object name '" + mbeanNameString
+ + "'; JMX support disabled", ex);
+ enabled = false;
+ }
+ this.mbeanInstance = mbeanInstance;
+ }
+
+ public TransportMBeanSupport(TransportListener listener, String name) {
+ this(name + "-listener", new TransportView(listener, null));
+ }
+
+ public TransportMBeanSupport(TransportSender sender, String name) {
+ this(name + "-sender", new TransportView(null, sender));
+ }
+
+ public ObjectName getMBeanName() {
+ return mbeanName;
+ }
+
+ /**
+ * Register the {@link TransportView} MBean.
+ */
+ public void register() {
+ if (enabled && !registered) {
+ try {
+ mbs.registerMBean(mbeanInstance, mbeanName);
+ registered = true;
+ } catch (Exception e) {
+ log.warn("Error registering a MBean with objectname ' " + mbeanName +
+ " ' for JMX management", e);
+ enabled = false;
+ }
+ }
+ }
+
+ /**
+ * Unregister the {@link TransportView} MBean.
+ */
+ public void unregister() {
+ if (enabled && registered) {
+ try {
+ mbs.unregisterMBean(mbeanName);
+ registered = false;
+ } catch (Exception e) {
+ log.warn("Error un-registering a MBean with objectname ' " + mbeanName +
+ " ' for JMX management", e);
+ }
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportView.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportView.java
new file mode 100644
index 0000000..77cf5ec
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportView.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.axis2.transport.TransportListener;
+import org.apache.axis2.transport.TransportSender;
+
+import java.util.Map;
+
+public class TransportView implements TransportViewMBean {
+
+ private static final Log log = LogFactory.getLog(TransportView.class);
+
+ public static final int STOPPED = 0;
+ public static final int RUNNING = 1;
+ public static final int PAUSED = 2;
+ public static final int SHUTTING_DOWN = 3;
+
+ private TransportListener listener = null;
+ private TransportSender sender = null;
+
+ public TransportView(TransportListener listener, TransportSender sender) {
+ this.listener = listener;
+ this.sender = sender;
+ }
+
+ // JMX Attributes
+ public long getMessagesReceived() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getMessagesReceived();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getMessagesReceived();
+ }
+ return -1;
+ }
+
+ public long getFaultsReceiving() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getFaultsReceiving();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getFaultsReceiving();
+ }
+ return -1;
+ }
+
+ public long getTimeoutsReceiving() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getTimeoutsReceiving();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getTimeoutsReceiving();
+ }
+ return -1;
+ }
+
+ public long getTimeoutsSending() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getTimeoutsSending();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getTimeoutsSending();
+ }
+ return -1;
+ }
+
+ public long getBytesReceived() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getBytesReceived();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getBytesReceived();
+ }
+ return -1;
+ }
+
+ public long getMessagesSent() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getMessagesSent();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getMessagesSent();
+ }
+ return -1;
+ }
+
+ public long getFaultsSending() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getFaultsSending();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getFaultsSending();
+ }
+ return -1;
+ }
+
+ public long getBytesSent() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getBytesSent();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getBytesSent();
+ }
+ return -1;
+ }
+
+ public long getMinSizeReceived() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getMinSizeReceived();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getMinSizeReceived();
+ }
+ return -1;
+ }
+
+ public long getMaxSizeReceived() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getMaxSizeReceived();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getMaxSizeReceived();
+ }
+ return -1;
+ }
+
+ public double getAvgSizeReceived() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getAvgSizeReceived();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getAvgSizeReceived();
+ }
+ return -1;
+ }
+
+ public long getMinSizeSent() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getMinSizeSent();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getMinSizeSent();
+ }
+ return -1;
+ }
+
+ public long getMaxSizeSent() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getMaxSizeSent();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getMaxSizeSent();
+ }
+ return -1;
+ }
+
+ public double getAvgSizeSent() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getAvgSizeSent();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getAvgSizeSent();
+ }
+ return -1;
+ }
+
+ public Map getResponseCodeTable() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getResponseCodeTable();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getResponseCodeTable();
+ }
+ return null;
+ }
+
+ public int getActiveThreadCount() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getActiveThreadCount();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getActiveThreadCount();
+ }
+ return -1;
+ }
+
+ public int getQueueSize() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getQueueSize();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getQueueSize();
+ }
+ return -1;
+ }
+
+ // JMX Operations
+ public void start() throws Exception{
+ if (listener != null) {
+ listener.start();
+ }
+ }
+
+ public void stop() throws Exception {
+ if (listener != null) {
+ listener.stop();
+ } else if (sender != null) {
+ sender.stop();
+ }
+ }
+
+ public void pause() throws Exception {
+ if (listener instanceof ManagementSupport) {
+ ((ManagementSupport) listener).pause();
+ } else if (sender instanceof ManagementSupport) {
+ ((ManagementSupport) sender).pause();
+ }
+ }
+
+ public void resume() throws Exception {
+ if (listener instanceof ManagementSupport) {
+ ((ManagementSupport) listener).resume();
+ } else if (sender instanceof ManagementSupport) {
+ ((ManagementSupport) sender).resume();
+ }
+ }
+
+ public void maintenenceShutdown(long seconds) throws Exception {
+ if (listener instanceof ManagementSupport) {
+ ((ManagementSupport) listener).maintenenceShutdown(seconds * 1000);
+ } else if (sender instanceof ManagementSupport) {
+ ((ManagementSupport) sender).maintenenceShutdown(seconds * 1000);
+ }
+ }
+
+ public void resetStatistics() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ ((ManagementSupport) listener).resetStatistics();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ ((ManagementSupport) sender).resetStatistics();
+ }
+ }
+
+ public long getLastResetTime() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return ((ManagementSupport) listener).getLastResetTime();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return ((ManagementSupport) sender).getLastResetTime();
+ }
+ return -1;
+ }
+
+ public long getMetricsWindow() {
+ if (listener != null && listener instanceof ManagementSupport) {
+ return System.currentTimeMillis() - ((ManagementSupport) listener).getLastResetTime();
+ } else if (sender != null && sender instanceof ManagementSupport) {
+ return System.currentTimeMillis() - ((ManagementSupport) sender).getLastResetTime();
+ }
+ return -1;
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportViewMBean.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportViewMBean.java
new file mode 100644
index 0000000..71219eb
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/TransportViewMBean.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.axis2.transport.base;
+import java.util.Map;
+
+public interface TransportViewMBean {
+
+ // JMX Attributes
+ public long getMessagesReceived();
+ public long getFaultsReceiving();
+ public long getTimeoutsReceiving();
+ public long getMessagesSent();
+ public long getFaultsSending();
+ public long getTimeoutsSending();
+ public long getBytesReceived();
+ public long getBytesSent();
+ public long getMinSizeReceived();
+ public long getMaxSizeReceived();
+ public double getAvgSizeReceived();
+ public long getMinSizeSent();
+ public long getMaxSizeSent();
+ public double getAvgSizeSent();
+ public int getActiveThreadCount();
+ public int getQueueSize();
+ public Map getResponseCodeTable();
+
+ // JMX Operations
+ public void start() throws Exception;
+ public void stop() throws Exception;
+ public void pause() throws Exception;
+ public void resume() throws Exception;
+ public void maintenenceShutdown(long seconds) throws Exception;
+
+ public void resetStatistics();
+ public long getLastResetTime();
+ public long getMetricsWindow();
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/AbstractDatagramTransportListener.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/AbstractDatagramTransportListener.java
new file mode 100644
index 0000000..0baf1df
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/AbstractDatagramTransportListener.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.axis2.transport.base.datagram;
+
+import java.io.IOException;
+import java.net.SocketException;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.description.TransportInDescription;
+import org.apache.axis2.transport.base.AbstractTransportListenerEx;
+
+public abstract class AbstractDatagramTransportListener<E extends DatagramEndpoint>
+ extends AbstractTransportListenerEx<E> {
+
+ private DatagramDispatcher<E> dispatcher;
+ private String defaultIp;
+
+ @Override
+ public void init(ConfigurationContext cfgCtx, TransportInDescription transportIn)
+ throws AxisFault {
+
+ super.init(cfgCtx, transportIn);
+ DatagramDispatcherCallback callback = new DatagramDispatcherCallback() {
+ public void receive(DatagramEndpoint endpoint, byte[] data, int length) {
+ workerPool.execute(new ProcessPacketTask(endpoint, data, length));
+ }
+ };
+ try {
+ dispatcher = createDispatcher(callback);
+ } catch (IOException ex) {
+ throw new AxisFault("Unable to create selector", ex);
+ }
+ try {
+ defaultIp = org.apache.axis2.util.Utils.getIpAddress(cfgCtx.getAxisConfiguration());
+ } catch (SocketException ex) {
+ throw new AxisFault("Unable to determine the host's IP address", ex);
+ }
+ }
+
+ @Override
+ protected final E createEndpoint() {
+ E endpoint = doCreateEndpoint();
+ endpoint.setMetrics(metrics);
+ return endpoint;
+ }
+
+ protected abstract E doCreateEndpoint();
+
+ @Override
+ protected void startEndpoint(E endpoint) throws AxisFault {
+ try {
+ dispatcher.addEndpoint(endpoint);
+ } catch (IOException ex) {
+ throw new AxisFault("Unable to listen on endpoint "
+ + endpoint.getEndpointReferences(defaultIp)[0], ex);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Started listening on endpoint " + endpoint.getEndpointReferences(defaultIp)[0]
+ + " [contentType=" + endpoint.getContentType()
+ + "; service=" + endpoint.getServiceName() + "]");
+ }
+ }
+
+ @Override
+ protected void stopEndpoint(E endpoint) {
+ try {
+ dispatcher.removeEndpoint(endpoint);
+ } catch (IOException ex) {
+ log.error("I/O exception while stopping listener for service " + endpoint.getServiceName(), ex);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ try {
+ dispatcher.stop();
+ } catch (IOException ex) {
+ log.error("Failed to stop dispatcher", ex);
+ }
+ }
+
+ protected abstract DatagramDispatcher<E> createDispatcher(DatagramDispatcherCallback callback)
+ throws IOException;
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramDispatcher.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramDispatcher.java
new file mode 100644
index 0000000..dac82c0
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramDispatcher.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base.datagram;
+
+import java.io.IOException;
+
+public interface DatagramDispatcher<E> {
+ void addEndpoint(E endpoint) throws IOException;
+ void removeEndpoint(E endpoint) throws IOException;
+ void stop() throws IOException;
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramDispatcherCallback.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramDispatcherCallback.java
new file mode 100644
index 0000000..5ededb5
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramDispatcherCallback.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.axis2.transport.base.datagram;
+
+public interface DatagramDispatcherCallback {
+ void receive(DatagramEndpoint endpoint, byte[] data, int length);
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramEndpoint.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramEndpoint.java
new file mode 100644
index 0000000..b2cf6f4
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/DatagramEndpoint.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.transport.base.datagram;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.ParameterInclude;
+import org.apache.axis2.transport.base.MetricsCollector;
+import org.apache.axis2.transport.base.ParamUtils;
+import org.apache.axis2.transport.base.ProtocolEndpoint;
+
+/**
+ * Endpoint description.
+ * This class is used by the transport to store information
+ * about an endpoint, e.g. the Axis service it is bound to.
+ * Transports extend this abstract class to store additional
+ * transport specific information, such as the port number
+ * the transport listens on.
+ */
+public abstract class DatagramEndpoint extends ProtocolEndpoint {
+ private String contentType;
+ private MetricsCollector metrics;
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public MetricsCollector getMetrics() {
+ return metrics;
+ }
+
+ public void setMetrics(MetricsCollector metrics) {
+ this.metrics = metrics;
+ }
+
+ @Override
+ public boolean loadConfiguration(ParameterInclude params) throws AxisFault {
+ contentType = ParamUtils.getRequiredParam(
+ params, "transport." + getListener().getTransportName() + ".contentType");
+ return true;
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/ProcessPacketTask.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/ProcessPacketTask.java
new file mode 100644
index 0000000..c56bd13
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/ProcessPacketTask.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base.datagram;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.engine.AxisEngine;
+import org.apache.axis2.transport.TransportUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.axis2.transport.base.MetricsCollector;
+
+/**
+ * Task encapsulating the processing of a datagram.
+ * Instances of this class will be dispatched to worker threads for
+ * execution.
+ */
+public class ProcessPacketTask implements Runnable {
+ private static final Log log = LogFactory.getLog(ProcessPacketTask.class);
+
+ private final DatagramEndpoint endpoint;
+ private final byte[] data;
+ private final int length;
+
+ public ProcessPacketTask(DatagramEndpoint endpoint, byte[] data, int length) {
+ this.endpoint = endpoint;
+ this.data = data;
+ this.length = length;
+ }
+
+ public void run() {
+ MetricsCollector metrics = endpoint.getMetrics();
+ try {
+ InputStream inputStream = new ByteArrayInputStream(data, 0, length);
+ MessageContext msgContext = endpoint.createMessageContext();
+ SOAPEnvelope envelope = TransportUtils.createSOAPMessage(msgContext, inputStream, endpoint.getContentType());
+ msgContext.setEnvelope(envelope);
+ AxisEngine.receive(msgContext);
+ metrics.incrementMessagesReceived();
+ metrics.incrementBytesReceived(length);
+ } catch (Exception ex) {
+ metrics.incrementFaultsReceiving();
+ StringBuilder buffer = new StringBuilder("Error during processing of datagram:\n");
+ Utils.hexDump(buffer, data, length);
+ log.error(buffer.toString(), ex);
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/Utils.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/Utils.java
new file mode 100644
index 0000000..3954bb3
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/Utils.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.axis2.transport.base.datagram;
+
+/**
+ * Utility class with methods used by datagram transports.
+ */
+public class Utils {
+ private Utils() {}
+
+ public static void hexDump(StringBuilder buffer, byte[] data, int length) {
+ for (int start = 0; start < length; start += 16) {
+ for (int i=0; i<16; i++) {
+ int index = start+i;
+ if (index < length) {
+ String hex = Integer.toHexString(data[start+i] & 0xFF);
+ if (hex.length() < 2) {
+ buffer.append('0');
+ }
+ buffer.append(hex);
+ } else {
+ buffer.append(" ");
+ }
+ buffer.append(' ');
+ if (i == 7) {
+ buffer.append(' ');
+ }
+ }
+ buffer.append(" |");
+ for (int i=0; i<16; i++) {
+ int index = start+i;
+ if (index < length) {
+ int b = data[index] & 0xFF;
+ if (32 <= b && b < 128) {
+ buffer.append((char)b);
+ } else {
+ buffer.append('.');
+ }
+ } else {
+ buffer.append(' ');
+ }
+ }
+ buffer.append('|');
+ buffer.append('\n');
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/package-info.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/package-info.java
new file mode 100644
index 0000000..0a79235
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/datagram/package-info.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.
+ */
+
+/**
+ * Base classes for datagram transports.
+ * <p>
+ * A datagram type transport is a transport that entirely reads a message
+ * into memory before starting to process it: in contrast to transports like HTTP,
+ * it doesn't support streaming. This approach can be chosen either because
+ * of the characteristics of the underlying protocol (such as in the case of UDP)
+ * or because streaming a message would unnecessarily delay the processing of the
+ * next available message (as in the case of a UNIX pipe).
+ */
+package org.apache.axis2.transport.base.datagram;
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportError.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportError.java
new file mode 100644
index 0000000..6808859
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportError.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.transport.base.event;
+
+import org.apache.axis2.description.AxisService;
+
+public class TransportError {
+ private final Object source;
+ private final AxisService service;
+ private final Throwable exception;
+
+ public TransportError(Object source, AxisService service, Throwable exception) {
+ this.source = source;
+ this.service = service;
+ this.exception = exception;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public AxisService getService() {
+ return service;
+ }
+
+ public Throwable getException() {
+ return exception;
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorListener.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorListener.java
new file mode 100644
index 0000000..2bb7c3b
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorListener.java
@@ -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.
+ */
+
+package org.apache.axis2.transport.base.event;
+
+public interface TransportErrorListener {
+ void error(TransportError error);
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorSource.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorSource.java
new file mode 100644
index 0000000..d87e559
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorSource.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base.event;
+
+public interface TransportErrorSource {
+ void addErrorListener(TransportErrorListener listener);
+ void removeErrorListener(TransportErrorListener listener);
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorSourceSupport.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorSourceSupport.java
new file mode 100644
index 0000000..f4c7b69
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/event/TransportErrorSourceSupport.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base.event;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.axis2.description.AxisService;
+
+public class TransportErrorSourceSupport implements TransportErrorSource {
+ private final Object source;
+ private final List<TransportErrorListener> listeners = new LinkedList<TransportErrorListener>();
+
+ public TransportErrorSourceSupport(Object source) {
+ this.source = source;
+ }
+
+ public synchronized void addErrorListener(TransportErrorListener listener) {
+ listeners.add(listener);
+ }
+
+ public synchronized void removeErrorListener(TransportErrorListener listener) {
+ listeners.remove(listener);
+ }
+
+ public synchronized void error(AxisService service, Throwable ex) {
+ if (!listeners.isEmpty()) {
+ TransportError error = new TransportError(source, service, ex);
+ for (TransportErrorListener listener : listeners) {
+ listener.error(error);
+ }
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/streams/ReaderInputStream.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/streams/ReaderInputStream.java
new file mode 100644
index 0000000..6846316
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/streams/ReaderInputStream.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.axis2.transport.base.streams;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+
+/**
+ * {@link InputStream} implementation that reads a character stream from a {@link Reader}
+ * and transforms it to a byte stream using a specified charset encoding. The stream
+ * is transformed using a {@link CharsetEncoder} object, guaranteeing that all charset
+ * encodings supported by the JRE are handled correctly. In particular for charsets such as
+ * UTF-16, the implementation ensures that one and only one byte order marker
+ * is produced.
+ * <p>
+ * Since in general it is not possible to predict the number of characters to be read from the
+ * {@link Reader} to satisfy a read request on the {@link ReaderInputStream}, all reads from
+ * the {@link Reader} are buffered. There is therefore no well defined correlation
+ * between the current position of the {@link Reader} and that of the {@link ReaderInputStream}.
+ * This also implies that in general there is no need to wrap the underlying {@link Reader}
+ * in a {@link java.io.BufferedReader}.
+ * <p>
+ * {@link ReaderInputStream} implements the inverse transformation of {@link java.io.InputStreamReader};
+ * in the following example, reading from <tt>in2</tt> would return the same byte
+ * sequence as reading from <tt>in</tt> (provided that the initial byte sequence is legal
+ * with respect to the charset encoding):
+ * <pre>
+ * InputStream in = ...
+ * Charset cs = ...
+ * InputStreamReader reader = new InputStreamReader(in, cs);
+ * ReaderInputStream in2 = new ReaderInputStream(reader, cs);</pre>
+ * {@link ReaderInputStream} implements the same transformation as {@link java.io.OutputStreamWriter},
+ * except that the control flow is reversed: both classes transform a character stream
+ * into a byte stream, but {@link java.io.OutputStreamWriter} pushes data to the underlying stream,
+ * while {@link ReaderInputStream} pulls it from the underlying stream.
+ * <p>
+ * Note that while there are use cases where there is no alternative to using
+ * this class, very often the need to use this class is an indication of a flaw
+ * in the design of the code. This class is typically used in situations where an existing
+ * API only accepts an {@link InputStream}, but where the most natural way to produce the data
+ * is as a character stream, i.e. by providing a {@link Reader} instance. An example of a situation
+ * where this problem may appear is when implementing the {@link javax.activation.DataSource}
+ * interface from the Java Activation Framework.
+ * <p>
+ * Given the fact that the {@link Reader} class doesn't provide any way to predict whether the next
+ * read operation will block or not, it is not possible to provide a meaningful
+ * implementation of the {@link InputStream#available()} method. A call to this method
+ * will always return 0. Also, this class doesn't support {@link InputStream#mark(int)}.
+ * <p>
+ * Instances of {@link ReaderInputStream} are not thread safe.
+ */
+// NOTE: Remove this class once Commons IO 2.0 is available (see IO-158)
+public class ReaderInputStream extends InputStream {
+ private static final int DEFAULT_BUFFER_SIZE = 1024;
+
+ private final Reader reader;
+ private final CharsetEncoder encoder;
+
+ /**
+ * CharBuffer used as input for the decoder. It should be reasonably
+ * large as we read data from the underlying Reader into this buffer.
+ */
+ private final CharBuffer encoderIn;
+
+ /**
+ * ByteBuffer used as output for the decoder. This buffer can be small
+ * as it is only used to transfer data from the decoder to the
+ * buffer provided by the caller.
+ */
+ private final ByteBuffer encoderOut = ByteBuffer.allocate(128);
+
+ private CoderResult lastCoderResult;
+ private boolean endOfInput;
+
+ /**
+ * Construct a new {@link ReaderInputStream}.
+ *
+ * @param reader the target {@link Reader}
+ * @param charset the charset encoding
+ * @param bufferSize the size of the input buffer in number of characters
+ */
+ public ReaderInputStream(Reader reader, Charset charset, int bufferSize) {
+ this.reader = reader;
+ encoder = charset.newEncoder();
+ encoderIn = CharBuffer.allocate(bufferSize);
+ encoderIn.flip();
+ }
+
+ /**
+ * Construct a new {@link ReaderInputStream} with a default input buffer size of
+ * 1024 characters.
+ *
+ * @param reader the target {@link Reader}
+ * @param charset the charset encoding
+ */
+ public ReaderInputStream(Reader reader, Charset charset) {
+ this(reader, charset, DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * Construct a new {@link ReaderInputStream}.
+ *
+ * @param reader the target {@link Reader}
+ * @param charsetName the name of the charset encoding
+ * @param bufferSize the size of the input buffer in number of characters
+ */
+ public ReaderInputStream(Reader reader, String charsetName, int bufferSize) {
+ this(reader, Charset.forName(charsetName), bufferSize);
+ }
+
+ /**
+ * Construct a new {@link ReaderInputStream} with a default input buffer size of
+ * 1024 characters.
+ *
+ * @param reader the target {@link Reader}
+ * @param charsetName the name of the charset encoding
+ */
+ public ReaderInputStream(Reader reader, String charsetName) {
+ this(reader, charsetName, DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * Construct a new {@link ReaderInputStream} that uses the default character encoding
+ * with a default input buffer size of 1024 characters.
+ *
+ * @param reader the target {@link Reader}
+ */
+ public ReaderInputStream(Reader reader) {
+ this(reader, Charset.defaultCharset());
+ }
+
+ /**
+ * Read the specified number of bytes into an array.
+ *
+ * @param b the byte array to read into
+ * @param off the offset to start reading bytes into
+ * @param len the number of bytes to read
+ * @return the number of bytes read or <code>-1</code>
+ * if the end of the stream has been reached
+ */
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ int read = 0;
+ while (len > 0) {
+ if (encoderOut.position() > 0) {
+ encoderOut.flip();
+ int c = Math.min(encoderOut.remaining(), len);
+ encoderOut.get(b, off, c);
+ off += c;
+ len -= c;
+ read += c;
+ encoderOut.compact();
+ } else {
+ if (!endOfInput && (lastCoderResult == null || lastCoderResult.isUnderflow())) {
+ encoderIn.compact();
+ int position = encoderIn.position();
+ // We don't use Reader#read(CharBuffer) here because it is more efficient
+ // to write directly to the underlying char array (the default implementation
+ // copies data to a temporary char array).
+ int c = reader.read(encoderIn.array(), position, encoderIn.remaining());
+ if (c == -1) {
+ endOfInput = true;
+ } else {
+ encoderIn.position(position+c);
+ }
+ encoderIn.flip();
+ }
+ lastCoderResult = encoder.encode(encoderIn, encoderOut, endOfInput);
+ if (endOfInput && encoderOut.position() == 0) {
+ break;
+ }
+ }
+ }
+ return read == 0 && endOfInput ? -1 : read;
+ }
+
+ /**
+ * Read the specified number of bytes into an array.
+ *
+ * @param b the byte array to read into
+ * @return the number of bytes read or <code>-1</code>
+ * if the end of the stream has been reached
+ */
+ @Override
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ /**
+ * Read a single byte.
+ *
+ * @return either the byte read or <code>-1</code> if the end of the stream
+ * has been reached
+ */
+ @Override
+ public int read() throws IOException {
+ byte[] b = new byte[1];
+ return read(b) == -1 ? -1 : b[0] & 0xFF;
+ }
+
+ /**
+ * Close the stream. This method will cause the underlying {@link Reader}
+ * to be closed.
+ */
+ @Override
+ public void close() throws IOException {
+ reader.close();
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/streams/WriterOutputStream.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/streams/WriterOutputStream.java
new file mode 100644
index 0000000..07cf744
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/streams/WriterOutputStream.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base.streams;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * {@link OutputStream} implementation that transforms a byte stream to a
+ * character stream using a specified charset encoding and writes the resulting
+ * stream to a {@link Writer}. The stream is transformed using a
+ * {@link CharsetDecoder} object, guaranteeing that all charset
+ * encodings supported by the JRE are handled correctly.
+ * <p>
+ * The output of the {@link CharsetDecoder} is buffered using a fixed size buffer.
+ * This implies that the data is written to the underlying {@link Writer} in chunks
+ * that are no larger than the size of this buffer. By default, the buffer is
+ * flushed only when it overflows or when {@link #flush()} or {@link #close()}
+ * is called. In general there is therefore no need to wrap the underlying {@link Writer}
+ * in a {@link java.io.BufferedWriter}. {@link WriterOutputStream} can also
+ * be instructed to flush the buffer after each write operation. In this case, all
+ * available data is written immediately to the underlying {@link Writer}, implying that
+ * the current position of the {@link Writer} is correlated to the current position
+ * of the {@link WriterOutputStream}.
+ * <p>
+ * {@link WriterOutputStream} implements the inverse transformation of {@link java.io.OutputStreamWriter};
+ * in the following example, writing to <tt>out2</tt> would have the same result as writing to
+ * <tt>out</tt> directly (provided that the byte sequence is legal with respect to the
+ * charset encoding):
+ * <pre>
+ * OutputStream out = ...
+ * Charset cs = ...
+ * OutputStreamWriter writer = new OutputStreamWriter(out, cs);
+ * WriterOutputStream out2 = new WriterOutputStream(writer, cs);</pre>
+ * {@link WriterOutputStream} implements the same transformation as {@link java.io.InputStreamReader},
+ * except that the control flow is reversed: both classes transform a byte stream
+ * into a character stream, but {@link java.io.InputStreamReader} pulls data from the underlying stream,
+ * while {@link WriterOutputStream} pushes it to the underlying stream.
+ * <p>
+ * Note that while there are use cases where there is no alternative to using
+ * this class, very often the need to use this class is an indication of a flaw
+ * in the design of the code. This class is typically used in situations where an existing
+ * API only accepts an {@link OutputStream} object, but where the stream is known to represent
+ * character data that must be decoded for further use.
+ * <p>
+ * Instances of {@link WriterOutputStream} are not thread safe.
+ */
+//NOTE: Remove this class once Commons IO 2.0 is available (see IO-158)
+public class WriterOutputStream extends OutputStream {
+ private static final int DEFAULT_BUFFER_SIZE = 1024;
+
+ private final Writer writer;
+ private final CharsetDecoder decoder;
+ private final boolean writeImmediately;
+
+ /**
+ * ByteBuffer used as input for the decoder. This buffer can be small
+ * as it is used only to transfer the received data to the
+ * decoder.
+ */
+ private final ByteBuffer decoderIn = ByteBuffer.allocate(128);
+
+ /**
+ * CharBuffer used as output for the decoder. It should be
+ * somewhat larger as we write from this buffer to the
+ * underlying Writer.
+ */
+ private final CharBuffer decoderOut;
+
+ /**
+ * Constructs a new {@link WriterOutputStream}.
+ *
+ * @param writer the target {@link Writer}
+ * @param charset the charset encoding
+ * @param bufferSize the size of the output buffer in number of characters
+ * @param writeImmediately If <tt>true</tt> the output buffer will be flushed after each
+ * write operation, i.e. all available data will be written to the
+ * underlying {@link Writer} immediately. If <tt>false</tt>, the
+ * output buffer will only be flushed when it overflows or when
+ * {@link #flush()} or {@link #close()} is called.
+ */
+ public WriterOutputStream(Writer writer, Charset charset, int bufferSize, boolean writeImmediately) {
+ this.writer = writer;
+ decoder = charset.newDecoder();
+ decoder.onMalformedInput(CodingErrorAction.REPLACE);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ decoder.replaceWith("?");
+ this.writeImmediately = writeImmediately;
+ decoderOut = CharBuffer.allocate(bufferSize);
+ }
+
+ /**
+ * Constructs a new {@link WriterOutputStream} with a default output buffer size of
+ * 1024 characters. The output buffer will only be flushed when it overflows or when
+ * {@link #flush()} or {@link #close()} is called.
+ *
+ * @param writer the target {@link Writer}
+ * @param charset the charset encoding
+ */
+ public WriterOutputStream(Writer writer, Charset charset) {
+ this(writer, charset, DEFAULT_BUFFER_SIZE, false);
+ }
+
+ /**
+ * Constructs a new {@link WriterOutputStream}.
+ *
+ * @param writer the target {@link Writer}
+ * @param charsetName the name of the charset encoding
+ * @param bufferSize the size of the output buffer in number of characters
+ * @param writeImmediately If <tt>true</tt> the output buffer will be flushed after each
+ * write operation, i.e. all available data will be written to the
+ * underlying {@link Writer} immediately. If <tt>false</tt>, the
+ * output buffer will only be flushed when it overflows or when
+ * {@link #flush()} or {@link #close()} is called.
+ */
+ public WriterOutputStream(Writer writer, String charsetName, int bufferSize, boolean writeImmediately) {
+ this(writer, Charset.forName(charsetName), bufferSize, writeImmediately);
+ }
+
+ /**
+ * Constructs a new {@link WriterOutputStream} with a default output buffer size of
+ * 1024 characters. The output buffer will only be flushed when it overflows or when
+ * {@link #flush()} or {@link #close()} is called.
+ *
+ * @param writer the target {@link Writer}
+ * @param charsetName the name of the charset encoding
+ */
+ public WriterOutputStream(Writer writer, String charsetName) {
+ this(writer, charsetName, DEFAULT_BUFFER_SIZE, false);
+ }
+
+ /**
+ * Constructs a new {@link WriterOutputStream} that uses the default character encoding
+ * and with a default output buffer size of 1024 characters. The output buffer will only
+ * be flushed when it overflows or when {@link #flush()} or {@link #close()} is called.
+ *
+ * @param writer the target {@link Writer}
+ */
+ public WriterOutputStream(Writer writer) {
+ this(writer, Charset.defaultCharset(), DEFAULT_BUFFER_SIZE, false);
+ }
+
+ /**
+ * Write bytes from the specified byte array to the stream.
+ *
+ * @param b the byte array containing the bytes to write
+ * @param off the start offset in the byte array
+ * @param len the number of bytes to write
+ */
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ while (len > 0) {
+ int c = Math.min(len, decoderIn.remaining());
+ decoderIn.put(b, off, c);
+ processInput(false);
+ len -= c;
+ off += c;
+ }
+ if (writeImmediately) {
+ flushOutput();
+ }
+ }
+
+ /**
+ * Write bytes from the specified byte array to the stream.
+ *
+ * @param b the byte array containing the bytes to write
+ */
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ /**
+ * Write a single byte to the stream.
+ *
+ * @param b the byte to write
+ */
+ @Override
+ public void write(int b) throws IOException {
+ write(new byte[] { (byte)b }, 0, 1);
+ }
+
+ /**
+ * Flush the stream. Any remaining content accumulated in the output buffer
+ * will be written to the underlying {@link Writer}. After that
+ * {@link Writer#flush()} will be called.
+ */
+ @Override
+ public void flush() throws IOException {
+ flushOutput();
+ writer.flush();
+ }
+
+ /**
+ * Close the stream. Any remaining content accumulated in the output buffer
+ * will be written to the underlying {@link Writer}. After that
+ * {@link Writer#close()} will be called.
+ */
+ @Override
+ public void close() throws IOException {
+ processInput(true);
+ flushOutput();
+ writer.close();
+ }
+
+ private void processInput(boolean endOfInput) throws IOException {
+ // Prepare decoderIn for reading
+ decoderIn.flip();
+ CoderResult coderResult;
+ while (true) {
+ coderResult = decoder.decode(decoderIn, decoderOut, endOfInput);
+ if (coderResult.isOverflow()) {
+ flushOutput();
+ } else if (coderResult.isUnderflow()) {
+ break;
+ } else {
+ // The decoder is configured to replace malformed input and unmappable characters,
+ // so we should not get here.
+ throw new IOException("Unexpected coder result");
+ }
+ }
+ // Discard the bytes that have been read
+ decoderIn.compact();
+ }
+
+ private void flushOutput() throws IOException {
+ if (decoderOut.position() > 0) {
+ writer.write(decoderOut.array(), 0, decoderOut.position());
+ decoderOut.rewind();
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/NativeThreadFactory.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/NativeThreadFactory.java
new file mode 100644
index 0000000..fe771ed
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/NativeThreadFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.transport.base.threads;
+
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * This is a simple ThreadFactory implementation using java.util.concurrent
+ * Creates threads with the given name prefix
+ */
+public class NativeThreadFactory implements
+ ThreadFactory {
+
+ final ThreadGroup group;
+ final AtomicInteger count;
+ final String namePrefix;
+
+ public NativeThreadFactory(final ThreadGroup group, final String namePrefix) {
+ super();
+ this.count = new AtomicInteger(1);
+ this.group = group;
+ this.namePrefix = namePrefix;
+ }
+
+ public Thread newThread(final Runnable runnable) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(this.namePrefix);
+ buffer.append('-');
+ buffer.append(this.count.getAndIncrement());
+ Thread t = new Thread(group, runnable, buffer.toString(), 0);
+ t.setDaemon(false);
+ t.setPriority(Thread.NORM_PRIORITY);
+ return t;
+ }
+}
\ No newline at end of file
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/NativeWorkerPool.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/NativeWorkerPool.java
new file mode 100644
index 0000000..71c6b90
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/NativeWorkerPool.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base.threads;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Worker pool implementation based on java.util.concurrent in JDK 1.5 or later.
+ */
+public class NativeWorkerPool implements WorkerPool {
+
+ static final Log log = LogFactory.getLog(NativeWorkerPool.class);
+
+ private final ThreadPoolExecutor executor;
+ private final LinkedBlockingQueue<Runnable> blockingQueue;
+
+ public NativeWorkerPool(int core, int max, int keepAlive,
+ int queueLength, String threadGroupName, String threadGroupId) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("Using native util.concurrent package..");
+ }
+ blockingQueue =
+ (queueLength == -1 ? new LinkedBlockingQueue<Runnable>()
+ : new LinkedBlockingQueue<Runnable>(queueLength));
+ executor = new ThreadPoolExecutor(
+ core, max, keepAlive,
+ TimeUnit.SECONDS,
+ blockingQueue,
+ new NativeThreadFactory(new ThreadGroup(threadGroupName), threadGroupId));
+ }
+
+ public void execute(final Runnable task) {
+ executor.execute(new Runnable() {
+ public void run() {
+ try {
+ task.run();
+ } catch (Throwable t) {
+ log.error("Uncaught exception", t);
+ }
+ }
+ });
+ }
+
+ public int getActiveCount() {
+ return executor.getActiveCount();
+ }
+
+ public int getQueueSize() {
+ return blockingQueue.size();
+ }
+
+ public void shutdown(int timeout) throws InterruptedException {
+ executor.shutdown();
+ executor.awaitTermination(timeout, TimeUnit.MILLISECONDS);
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/WorkerPool.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/WorkerPool.java
new file mode 100644
index 0000000..a05bf95
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/WorkerPool.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.transport.base.threads;
+
+public interface WorkerPool {
+ /**
+ * Asynchronously execute the given task using one of the threads of the worker pool.
+ * The task is expected to terminate gracefully, i.e. {@link Runnable#run()} should not
+ * throw an exception. Any uncaught exceptions should be logged by the worker pool
+ * implementation.
+ *
+ * @param task the task to execute
+ */
+ public void execute(Runnable task);
+
+ public int getActiveCount();
+ public int getQueueSize();
+
+ /**
+ * Destroy the worker pool. The pool will immediately stop
+ * accepting new tasks. All previously submitted tasks will
+ * be executed. The method blocks until all tasks have
+ * completed execution, or the timeout occurs, or the current
+ * thread is interrupted, whichever happens first.
+ *
+ * @param timeout the timeout value in milliseconds
+ * @throws InterruptedException if the current thread was
+ * interrupted while waiting for pending tasks to
+ * finish execution
+ */
+ public void shutdown(int timeout) throws InterruptedException;
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/WorkerPoolFactory.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/WorkerPoolFactory.java
new file mode 100644
index 0000000..98fc87a
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/threads/WorkerPoolFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.transport.base.threads;
+
+/**
+ * Worker pool factory.
+ * For the moment this always creates {@link NativeWorkerPool} instances since
+ * we assume that we are running on Java 1.5 or above.
+ */
+public class WorkerPoolFactory {
+
+ public static WorkerPool getWorkerPool(int core, int max, int keepAlive,
+ int queueLength, String threadGroupName, String threadGroupId) {
+ return new NativeWorkerPool(
+ core, max, keepAlive, queueLength, threadGroupName, threadGroupId);
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceFilter.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceFilter.java
new file mode 100644
index 0000000..35c9e0a
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceFilter.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.transport.base.tracker;
+
+import org.apache.axis2.description.AxisService;
+
+/**
+ * Filter for {@link AxisService} instances. This interface is used by
+ * {@link AxisServiceTracker}.
+ */
+public interface AxisServiceFilter {
+ /**
+ * Examine whether a given service matches the filter criteria.
+ *
+ * @param service the service to examine
+ * @return <code>true</code> if the service matches the filter criteria
+ */
+ boolean matches(AxisService service);
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceTracker.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceTracker.java
new file mode 100644
index 0000000..b848ec6
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceTracker.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.axis2.transport.base.tracker;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.AxisModule;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.AxisServiceGroup;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.engine.AxisEvent;
+import org.apache.axis2.engine.AxisObserver;
+
+/**
+ * <p>Tracks services deployed in a given {@link AxisConfiguration}.
+ * The tracker is configured with references to three objects:</p>
+ * <ol>
+ * <li>An {@link AxisConfiguration} to watch.</li>
+ * <li>An {@link AxisServiceFilter} restricting the services to track.</li>
+ * <li>An {@link AxisServiceTrackerListener} receiving tracking events.</li>
+ * </ol>
+ * <p>An instance of this class maintains an up-to-date list of services
+ * satisfying all of the following criteria:</p>
+ * <ol>
+ * <li>The service is deployed in the given {@link AxisConfiguration}.</li>
+ * <li>The service is started, i.e. {@link AxisService#isActive()} returns true.</li>
+ * <li>The service matches the criteria specified by the given
+ * {@link AxisServiceFilter} instance.</li>
+ * </ol>
+ * <p>Whenever a service appears on the list, the tracker will call
+ * {@link AxisServiceTrackerListener#serviceAdded(AxisService)}. When a service disappears, it
+ * will call {@link AxisServiceTrackerListener#serviceRemoved(AxisService)}.</p>
+ * <p>When the tracker is created, it is initially in the stopped state. In this state no
+ * events will be sent to the listener. It can be started using {@link #start()} and stopped again
+ * using {@link #stop()}. The tracker list is defined to be empty when the tracker is in the
+ * stopped state. This implies that a call to {@link #start()} will generate
+ * {@link AxisServiceTrackerListener#serviceAdded(AxisService)} events for all services that meet
+ * the above criteria at that point in time. In the same way, {@link #stop()} will generate
+ * {@link AxisServiceTrackerListener#serviceRemoved(AxisService)} events for the current entries
+ * in the list.</p>
+ * <p>As a corollary the tracker guarantees that during a complete lifecycle (start-stop),
+ * there will be exactly one {@link AxisServiceTrackerListener#serviceRemoved(AxisService)} event
+ * for every {@link AxisServiceTrackerListener#serviceAdded(AxisService)} event and vice-versa.
+ * This property is important when the tracker is used to allocate resources for a dynamic set
+ * of services.</p>
+ *
+ * <h2>Limitations</h2>
+ *
+ * <p>The tracker is not able to detect property changes on services. E.g. if a service initially
+ * matches the filter criteria, but later changes so that it doesn't match the criteria any more,
+ * the tracker will not be able to detect this and the service will not be removed from the tracker
+ * list.</p>
+ */
+public class AxisServiceTracker {
+ private final AxisObserver observer = new AxisObserver() {
+ public void init(AxisConfiguration axisConfig) {}
+
+ public void serviceUpdate(AxisEvent event, final AxisService service) {
+ switch (event.getEventType()) {
+ case AxisEvent.SERVICE_DEPLOY:
+ case AxisEvent.SERVICE_START:
+ if (filter.matches(service)) {
+ boolean pending;
+ synchronized (lock) {
+ if (pending = (pendingActions != null)) {
+ pendingActions.add(new Runnable() {
+ public void run() {
+ serviceAdded(service);
+ }
+ });
+ }
+ }
+ if (!pending) {
+ serviceAdded(service);
+ }
+ }
+ break;
+ case AxisEvent.SERVICE_REMOVE:
+ case AxisEvent.SERVICE_STOP:
+ // Don't check filter here because the properties of the service may have
+ // changed in the meantime.
+ boolean pending;
+ synchronized (lock) {
+ if (pending = (pendingActions != null)) {
+ pendingActions.add(new Runnable() {
+ public void run() {
+ serviceRemoved(service);
+ }
+ });
+ }
+ }
+ if (!pending) {
+ serviceRemoved(service);
+ }
+ }
+ }
+
+ public void moduleUpdate(AxisEvent event, AxisModule module) {}
+ public void addParameter(Parameter param) throws AxisFault {}
+ public void removeParameter(Parameter param) throws AxisFault {}
+ public void deserializeParameters(OMElement parameterElement) throws AxisFault {}
+ public Parameter getParameter(String name) { return null; }
+ public ArrayList<Parameter> getParameters() { return null; }
+ public boolean isParameterLocked(String parameterName) { return false; }
+ public void serviceGroupUpdate(AxisEvent event, AxisServiceGroup serviceGroup) {}
+ };
+
+ private final AxisConfiguration config;
+ final AxisServiceFilter filter;
+ private final AxisServiceTrackerListener listener;
+
+ /**
+ * Object used to synchronize access to {@link #pendingActions} and {@link #services}.
+ */
+ final Object lock = new Object();
+
+ /**
+ * Queue for notifications received by the {@link AxisObserver} during startup of the tracker.
+ * We need this because the events may already be reflected in the list of services returned
+ * by {@link AxisConfiguration#getServices()} (getting the list of currently deployed services
+ * and adding the observer can't be done atomically). It also allows us to make sure that
+ * events are sent to the listener in the right order, e.g. when a service is being removed
+ * during startup of the tracker.
+ */
+ Queue<Runnable> pendingActions;
+
+ /**
+ * The current list of services. <code>null</code> if the tracker is stopped.
+ */
+ private Set<AxisService> services;
+
+ public AxisServiceTracker(AxisConfiguration config, AxisServiceFilter filter,
+ AxisServiceTrackerListener listener) {
+ this.config = config;
+ this.filter = filter;
+ this.listener = listener;
+ }
+
+ /**
+ * Check whether the tracker is started.
+ *
+ * @return <code>true</code> if the tracker is started
+ */
+ public boolean isStarted() {
+ return services != null;
+ }
+
+ /**
+ * Start the tracker.
+ *
+ * @throws IllegalStateException if the tracker has already been started
+ */
+ public void start() {
+ if (services != null) {
+ throw new IllegalStateException();
+ }
+ synchronized (lock) {
+ pendingActions = new LinkedList<Runnable>();
+ config.addObservers(observer);
+ services = new HashSet<AxisService>();
+ }
+ for (AxisService service : config.getServices().values()) {
+ if (service.isActive() && filter.matches(service)) {
+ serviceAdded(service);
+ }
+ }
+ while (true) {
+ Runnable action;
+ synchronized (lock) {
+ action = pendingActions.poll();
+ if (action == null) {
+ pendingActions = null;
+ break;
+ }
+ }
+ action.run();
+ }
+ }
+
+ void serviceAdded(AxisService service) {
+ // callListener may be false because the observer got an event for a service that
+ // was already in the initial list of services retrieved by AxisConfiguration#getServices.
+ boolean callListener;
+ synchronized (lock) {
+ callListener = services.add(service);
+ }
+ if (callListener) {
+ listener.serviceAdded(service);
+ }
+ }
+
+ void serviceRemoved(AxisService service) {
+ // callListener may be false because the observer invokes this method without applying the
+ // filter.
+ boolean callListener;
+ synchronized (lock) {
+ callListener = services.remove(service);
+ }
+ if (callListener) {
+ listener.serviceRemoved(service);
+ }
+ }
+
+ /**
+ * Stop the tracker.
+ *
+ * @throws IllegalStateException if the tracker is not started
+ */
+ public void stop() {
+ if (services == null) {
+ throw new IllegalStateException();
+ }
+ // TODO: This is very bad, but AxisConfiguration has no removeObserver method!
+ config.getObserversList().remove(observer);
+ for (AxisService service : services) {
+ listener.serviceRemoved(service);
+ }
+ services = null;
+ }
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceTrackerListener.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceTrackerListener.java
new file mode 100644
index 0000000..285d91d
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/AxisServiceTrackerListener.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.axis2.transport.base.tracker;
+
+import org.apache.axis2.description.AxisService;
+
+/**
+ * Listener for events generated by an {@link AxisServiceTracker}.
+ */
+public interface AxisServiceTrackerListener {
+ /**
+ * Inform the listener that a service has been added to tracker list.
+ *
+ * @param service the service that has been added to the tracker list
+ */
+ void serviceAdded(AxisService service);
+
+ /**
+ * Inform the listener that a service has been removed from the tracker list.
+ *
+ * @param service the service that has been removed from the tracker list
+ */
+ void serviceRemoved(AxisService service);
+}
diff --git a/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/package-info.java b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/package-info.java
new file mode 100644
index 0000000..30dc21e
--- /dev/null
+++ b/1.0.0/modules/base/src/main/java/org/apache/axis2/transport/base/tracker/package-info.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.
+ */
+
+/**
+ * Contains utility classes to track a dynamic set of services deployed in an
+ * Axis configuration.
+ *
+ * @see org.apache.axis2.transport.base.tracker.AxisServiceTracker
+ */
+package org.apache.axis2.transport.base.tracker;
\ No newline at end of file
diff --git a/1.0.0/modules/base/src/test/java/org/apache/axis2/format/CharacterStreamComparator.java b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/CharacterStreamComparator.java
new file mode 100644
index 0000000..155c8e5
--- /dev/null
+++ b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/CharacterStreamComparator.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import junit.framework.Assert;
+
+/**
+ * {@link Writer} implementation that compares the data written to it with another character
+ * sequence specified by a {@link Reader}.
+ * This class is meant to be used in JUnit test cases.
+ */
+public class CharacterStreamComparator extends Writer {
+ private final Reader in;
+ private final char[] compareBuffer = new char[1024];
+ private int position;
+
+ public CharacterStreamComparator(Reader in) {
+ this.in = in;
+ }
+
+ @Override
+ public void write(char[] buffer, int off, int len) throws IOException {
+ while (len > 0) {
+ int c = in.read(compareBuffer, 0, Math.min(compareBuffer.length, len));
+ if (c == -1) {
+ Assert.fail("The two streams have different lengths");
+ }
+ for (int i=0; i<c; i++) {
+ if (buffer[off] != compareBuffer[i]) {
+ Assert.fail("Character mismatch at position " + position);
+ }
+ off++;
+ len--;
+ position++;
+ }
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (in.read() != -1) {
+ Assert.fail("The two streams have different lengths");
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/test/java/org/apache/axis2/format/ElementHelperTest.java b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/ElementHelperTest.java
new file mode 100644
index 0000000..9786ed0
--- /dev/null
+++ b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/ElementHelperTest.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.SequenceInputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Vector;
+
+import javax.activation.DataSource;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMSourcedElement;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.impl.llom.OMSourcedElementImpl;
+import org.apache.axiom.om.impl.llom.util.AXIOMUtil;
+import org.apache.commons.io.IOUtils;
+
+public class ElementHelperTest extends TestCase {
+ private void compareStreams(Reader s1, Reader s2) throws IOException {
+ Writer comparator = new CharacterStreamComparator(s2);
+ IOUtils.copy(s1, comparator);
+ comparator.close();
+ }
+
+ public void testGetTextAsStreamWithSingleTextNode() throws Exception {
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ OMElement element = factory.createOMElement(new QName("a"));
+ factory.createOMText(element, "test");
+ Reader in = ElementHelper.getTextAsStream(element, true);
+ assertTrue(in instanceof StringReader);
+ assertEquals(element.getText(), IOUtils.toString(in));
+ }
+
+ public void testGetTextAsStreamWithNonTextChildren() throws Exception {
+ OMElement element = AXIOMUtil.stringToOM("<a>A<b>B</b>C</a>");
+ Reader in = new TextFromElementReader(element.getXMLStreamReader());
+ assertEquals(element.getText(), IOUtils.toString(in));
+ }
+
+ public void testGetTextAsStreamWithOMSourcedElement() throws Exception {
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ DataSource ds = new RandomDataSource(445566, 32, 128, 20000000);
+ QName qname = new QName("a");
+ Charset cs = Charset.forName("ascii");
+ OMSourcedElement element = new OMSourcedElementImpl(qname, factory,
+ new WrappedTextNodeOMDataSourceFromDataSource(qname, ds, cs));
+ Reader in = ElementHelper.getTextAsStream(element, true);
+ assertFalse(in instanceof StringReader);
+ compareStreams(new InputStreamReader(ds.getInputStream(), cs), in);
+ }
+
+ public void testGetTextAsStreamWithoutCaching() throws Exception {
+ DataSource ds = new RandomDataSource(654321, 64, 128, 20000000);
+ Vector<InputStream> v = new Vector<InputStream>();
+ v.add(new ByteArrayInputStream("<a>".getBytes("ascii")));
+ v.add(ds.getInputStream());
+ v.add(new ByteArrayInputStream("</a>".getBytes("ascii")));
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.FALSE);
+ XMLStreamReader reader = factory.createXMLStreamReader(
+ new SequenceInputStream(v.elements()), "ascii");
+ OMElement element = new StAXOMBuilder(reader).getDocumentElement();
+ Reader in = ElementHelper.getTextAsStream(element, false);
+ compareStreams(new InputStreamReader(ds.getInputStream(), "ascii"), in);
+ }
+
+ public void testWriteTextTo() throws Exception {
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ OMElement element = factory.createOMElement(new QName("a"));
+ factory.createOMText(element, "test");
+ StringWriter out = new StringWriter();
+ ElementHelper.writeTextTo(element, out, true);
+ assertEquals(element.getText(), out.toString());
+ }
+
+ public void testWriteTextToWithNonTextNodes() throws Exception {
+ OMElement element = AXIOMUtil.stringToOM("<a>A<b>B</b>C</a>");
+ StringWriter out = new StringWriter();
+ ElementHelper.writeTextTo(element, out, true);
+ assertEquals(element.getText(), out.toString());
+ }
+
+ public void testWriteTextToWithOMSourcedElement() throws Exception {
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ DataSource ds = new RandomDataSource(665544, 32, 128, 20000000);
+ QName qname = new QName("a");
+ OMSourcedElement element = new OMSourcedElementImpl(qname, factory,
+ new WrappedTextNodeOMDataSourceFromDataSource(qname, ds, Charset.forName("ascii")));
+ Reader in = new InputStreamReader(ds.getInputStream(), "ascii");
+ Writer out = new CharacterStreamComparator(in);
+ ElementHelper.writeTextTo(element, out, true); // cache doesn't matter here
+ out.close();
+ }
+}
diff --git a/1.0.0/modules/base/src/test/java/org/apache/axis2/format/ManagedDataSourceFactoryTest.java b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/ManagedDataSourceFactoryTest.java
new file mode 100644
index 0000000..fea1733
--- /dev/null
+++ b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/ManagedDataSourceFactoryTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.activation.DataSource;
+
+import junit.framework.TestCase;
+
+public class ManagedDataSourceFactoryTest extends TestCase {
+ /**
+ * Test that exceptions thrown by {@link DataSource#getInputStream()} are
+ * correctly propagated. Since {@link ManagedDataSourceFactory} uses dynamic
+ * proxies this aspect needs particular attention.
+ */
+ public void testExceptionPropagation() {
+ ManagedDataSource ds = ManagedDataSourceFactory.create(new DataSource() {
+ public String getContentType() {
+ return null;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ throw new IOException("TEST");
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ return null;
+ }
+
+ public String getName() {
+ return null;
+ }
+ });
+ try {
+ ds.getInputStream();
+ } catch (IOException ex) {
+ assertEquals("TEST", ex.getMessage());
+ }
+ }
+}
diff --git a/1.0.0/modules/base/src/test/java/org/apache/axis2/format/PlainTextFormatterTest.java b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/PlainTextFormatterTest.java
new file mode 100644
index 0000000..683f910
--- /dev/null
+++ b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/PlainTextFormatterTest.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.axis2.format;
+
+import java.io.ByteArrayOutputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.format.PlainTextFormatter;
+import org.apache.axis2.transport.base.BaseConstants;
+
+public class PlainTextFormatterTest extends TestCase {
+ private static final String testString = "\u00e0 peine arriv\u00e9s nous entr\u00e2mes dans sa chambre";
+
+ private MessageContext createMessageContext(String textPayload) throws AxisFault {
+ MessageContext messageContext = new MessageContext();
+ SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
+ SOAPEnvelope envelope = factory.getDefaultEnvelope();
+ OMElement textWrapper = factory.createOMElement(BaseConstants.DEFAULT_TEXT_WRAPPER);
+ textWrapper.setText(textPayload);
+ envelope.getBody().addChild(textWrapper);
+ messageContext.setEnvelope(envelope);
+ return messageContext;
+ }
+
+ private void testGetBytes(String encoding) throws Exception {
+ MessageContext messageContext = createMessageContext(testString);
+ OMOutputFormat format = new OMOutputFormat();
+ format.setCharSetEncoding(encoding);
+ byte[] bytes = new PlainTextFormatter().getBytes(messageContext, format);
+ assertEquals(testString, new String(bytes, encoding));
+ }
+
+ public void testGetBytesUTF8() throws Exception {
+ testGetBytes("UTF-8");
+ }
+
+ public void testGetBytesLatin1() throws Exception {
+ testGetBytes("ISO-8859-1");
+ }
+
+ private void testWriteTo(String encoding) throws Exception {
+ MessageContext messageContext = createMessageContext(testString);
+ OMOutputFormat format = new OMOutputFormat();
+ format.setCharSetEncoding(encoding);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ new PlainTextFormatter().writeTo(messageContext, format, baos, false);
+ assertEquals(testString, new String(baos.toByteArray(), encoding));
+ }
+
+ public void testWriteToUTF8() throws Exception {
+ testWriteTo("UTF-8");
+ }
+
+ public void testWriteToLatin1() throws Exception {
+ testWriteTo("ISO-8859-1");
+ }
+}
diff --git a/1.0.0/modules/base/src/test/java/org/apache/axis2/format/RandomDataSource.java b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/RandomDataSource.java
new file mode 100644
index 0000000..cd82aa1
--- /dev/null
+++ b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/RandomDataSource.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Random;
+
+import javax.activation.DataSource;
+
+public class RandomDataSource implements DataSource {
+ private final long seed;
+ private final int rangeStart;
+ private final int rangeEnd;
+ private final int length;
+
+ public RandomDataSource(long seed, int rangeStart, int rangeEnd, int length) {
+ this.seed = seed;
+ this.rangeStart = rangeStart;
+ this.rangeEnd = rangeEnd;
+ this.length = length;
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ public String getContentType() {
+ return null;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ final Random random = new Random(seed);
+ return new InputStream() {
+ private int position;
+
+ @Override
+ public int read() throws IOException {
+ if (position == length) {
+ return -1;
+ } else {
+ position++;
+ return random.nextInt(rangeEnd-rangeStart) + rangeStart;
+ }
+ }
+ };
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/1.0.0/modules/base/src/test/java/org/apache/axis2/format/TextFromElementReaderTest.java b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/TextFromElementReaderTest.java
new file mode 100644
index 0000000..9568e8e
--- /dev/null
+++ b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/TextFromElementReaderTest.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.axis2.format;
+
+import java.io.Reader;
+import java.io.StringReader;
+
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.commons.io.IOUtils;
+
+// Note: this class only contains a single test method because most aspects of TextFromElementReader
+// are actually tested by ElementHelperTest
+public class TextFromElementReaderTest extends TestCase {
+ /**
+ * Test that TextFromElementReader works correctly with a "naked" StAX parser.
+ *
+ * @throws Exception
+ */
+ public void testStAX() throws Exception {
+ XMLStreamReader reader = StAXUtils.createXMLStreamReader(new StringReader("<a>test</a>"));
+ Reader in = new TextFromElementReader(reader);
+ assertEquals("test", IOUtils.toString(in));
+ }
+}
diff --git a/1.0.0/modules/base/src/test/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceTest.java b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceTest.java
new file mode 100644
index 0000000..f8e09aa
--- /dev/null
+++ b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/WrappedTextNodeOMDataSourceTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT 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.axis2.format;
+
+import java.io.StringReader;
+import java.util.Random;
+
+import javax.xml.namespace.QName;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMSourcedElement;
+import org.apache.axiom.om.impl.llom.OMSourcedElementImpl;
+
+public class WrappedTextNodeOMDataSourceTest extends TestCase {
+ public void testFromReader() throws Exception {
+ Random random = new Random();
+ StringBuilder buffer = new StringBuilder(40000);
+ for (int i=0; i<40000; i++) {
+ buffer.append((char)(32 + random.nextInt(96)));
+ }
+ String testData = buffer.toString();
+ QName qname = new QName("data");
+ OMDataSource ds = new WrappedTextNodeOMDataSourceFromReader(qname, new StringReader(testData));
+ OMFactory factory = OMAbstractFactory.getOMFactory();
+ OMSourcedElement element = new OMSourcedElementImpl(qname, factory, ds);
+ assertEquals(testData, element.getText());
+ }
+}
diff --git a/1.0.0/modules/base/src/test/java/org/apache/axis2/format/WrappedTextNodeStreamReaderTest.java b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/WrappedTextNodeStreamReaderTest.java
new file mode 100644
index 0000000..d36206f
--- /dev/null
+++ b/1.0.0/modules/base/src/test/java/org/apache/axis2/format/WrappedTextNodeStreamReaderTest.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.format;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.impl.serialize.StreamingOMSerializer;
+import org.custommonkey.xmlunit.XMLTestCase;
+
+public class WrappedTextNodeStreamReaderTest extends XMLTestCase {
+ //
+ // Tests that construct the Axiom tree and check the result
+ //
+
+ private void testUsingBuilder(QName wrapperElementName,
+ String testString,
+ int chunkSize) {
+ StringReader reader = new StringReader(testString);
+ XMLStreamReader xmlStreamReader
+ = new WrappedTextNodeStreamReader(wrapperElementName, reader, chunkSize);
+ OMElement element = new StAXOMBuilder(xmlStreamReader).getDocumentElement();
+ assertEquals(wrapperElementName, element.getQName());
+ assertEquals(wrapperElementName.getPrefix(), element.getQName().getPrefix());
+ assertEquals(testString, element.getText());
+ }
+
+ public void testShortStringUsingBuilder() {
+ testUsingBuilder(
+ new QName("urn:test", "test"),
+ "This is a test string for WrappedTextNodeStreamReader",
+ 4096);
+ }
+
+ public void testLongStringUsingBuilder() {
+ // "Long" is relative to the chunk size
+ testUsingBuilder(
+ new QName("urn:test", "test"),
+ "This is a test string for WrappedTextNodeStreamReader",
+ 10);
+ }
+
+ public void testWrapperElementWithoutNamespaceUsingBuilder() {
+ testUsingBuilder(
+ new QName("test"),
+ "This is a test string for WrappedTextNodeStreamReader",
+ 4096);
+ }
+
+ public void testWrapperElementWithPrefixUsingBuilder() {
+ testUsingBuilder(
+ new QName("urn:test", "bar", "foo"),
+ "This is a test string for WrappedTextNodeStreamReader",
+ 4096);
+ }
+
+ //
+ // Test that serialize the stream of XML events to plain XML and compare
+ // with the expected result.
+ //
+
+ private void testUsingSerializer(QName wrapperElementName,
+ String testString,
+ int chunkSize,
+ String expectedXML) throws Exception {
+ StringReader reader = new StringReader(testString);
+ XMLStreamReader xmlStreamReader
+ = new WrappedTextNodeStreamReader(wrapperElementName, reader, chunkSize);
+ StringWriter writer = new StringWriter();
+ XMLStreamWriter xmlStreamWriter
+ = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
+ new StreamingOMSerializer().serialize(xmlStreamReader, xmlStreamWriter);
+ xmlStreamWriter.flush();
+ assertXMLEqual(expectedXML, writer.toString());
+ }
+
+ public void testShortStringUsingSerializer() throws Exception {
+ String testString = "This is a test string for WrappedTextNodeStreamReader";
+ testUsingSerializer(
+ new QName("urn:test", "test"),
+ testString,
+ 4096,
+ "<test xmlns=\"urn:test\">" + testString + "</test>");
+ }
+
+ public void testLongStringUsingSerializer() throws Exception {
+ String testString = "This is a test string for WrappedTextNodeStreamReader";
+ testUsingSerializer(
+ new QName("urn:test", "test"),
+ testString,
+ 10,
+ "<test xmlns=\"urn:test\">" + testString + "</test>");
+ }
+
+ public void testStringWithAmpersandUsingSerializer() throws Exception {
+ testUsingSerializer(
+ new QName("urn:test", "test"),
+ "String containing ampersand (&)",
+ 4096,
+ "<test xmlns=\"urn:test\">String containing ampersand (&)</test>");
+ }
+
+ //
+ // Tests that construct the Axiom tree, serialize it using serializeAndConsume and
+ // compare with the expected result.
+ //
+
+ private void testUsingSerializeAndConsume(QName wrapperElementName,
+ String testString,
+ int chunkSize,
+ String expectedXML) throws Exception {
+ StringReader reader = new StringReader(testString);
+ XMLStreamReader xmlStreamReader
+ = new WrappedTextNodeStreamReader(wrapperElementName, reader, chunkSize);
+ OMElement element = new StAXOMBuilder(xmlStreamReader).getDocumentElement();
+ StringWriter writer = new StringWriter();
+ element.serializeAndConsume(writer);
+ assertXMLEqual(expectedXML, writer.toString());
+ }
+
+ public void testShortStringUsingSerializeAndConsume() throws Exception {
+ String testString = "This is a test string for WrappedTextNodeStreamReader";
+ testUsingSerializeAndConsume(
+ new QName("urn:test", "test"),
+ testString,
+ 4096,
+ "<test xmlns=\"urn:test\">" + testString + "</test>");
+ }
+}
diff --git a/1.0.0/modules/http/pom.xml b/1.0.0/modules/http/pom.xml
new file mode 100644
index 0000000..b03056b
--- /dev/null
+++ b/1.0.0/modules/http/pom.xml
@@ -0,0 +1,118 @@
+<?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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transports</artifactId>
+ <version>1.0.0</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <artifactId>axis2-transport-http-tests</artifactId>
+ <name>Apache Axis2 - Transport - HTTP Tests</name>
+ <description>This inclues all the available transports in Axis2</description>
+ <packaging>bundle</packaging>
+
+ <build>
+ <sourceDirectory>src</sourceDirectory>
+ <testSourceDirectory>test</testSourceDirectory>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <systemProperties>
+ <property>
+ <name>log4j.configuration</name>
+ <value>file:../../log4j.properties</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.4.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Version>1.0</Bundle-Version>
+ <Bundle-Name>${pom.artifactId}</Bundle-Name>
+ <Bundle-Vendor>Apache Software Foundation</Bundle-Vendor>
+ <Bundle-Description>${pom.description}</Bundle-Description>
+ <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+ <Export-Package>
+ org.apache.axis2.transport.http.*;-split-package:=merge-last,
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ <resources>
+ <resource>
+ <directory>conf</directory>
+ <excludes>
+ <exclude>**/*.properties</exclude>
+ </excludes>
+ <filtering>false</filtering>
+ </resource>
+ <resource>
+ <directory>src</directory>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+ <resource>
+ <directory>../..</directory>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-http</artifactId>
+ <version>${axis2.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-testkit</artifactId>
+ <version>${pom.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/1.0.0/modules/http/test/org/apache/axis2/transport/http/HttpTransportDescriptionFactory.java b/1.0.0/modules/http/test/org/apache/axis2/transport/http/HttpTransportDescriptionFactory.java
new file mode 100644
index 0000000..848abb7
--- /dev/null
+++ b/1.0.0/modules/http/test/org/apache/axis2/transport/http/HttpTransportDescriptionFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.transport.http;
+
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.description.TransportInDescription;
+import org.apache.axis2.description.TransportOutDescription;
+import org.apache.axis2.transport.testkit.axis2.TransportDescriptionFactory;
+import org.apache.axis2.transport.testkit.util.LifecycleFixTransportListenerProxy;
+
+public class HttpTransportDescriptionFactory implements TransportDescriptionFactory {
+ private final int port;
+
+ public HttpTransportDescriptionFactory(int port) {
+ this.port = port;
+ }
+
+ public TransportInDescription createTransportInDescription() throws Exception {
+ TransportInDescription desc = new TransportInDescription("http");
+ desc.setReceiver(new LifecycleFixTransportListenerProxy(new SimpleHTTPServer(), port));
+ desc.addParameter(new Parameter(SimpleHTTPServer.PARAM_PORT, String.valueOf(port)));
+ return desc;
+ }
+
+ public TransportOutDescription createTransportOutDescription() throws Exception {
+ TransportOutDescription desc = new TransportOutDescription("http");
+ desc.setSender(new CommonsHTTPTransportSender());
+ return desc;
+ }
+}
diff --git a/1.0.0/modules/http/test/org/apache/axis2/transport/http/SimpleHTTPServerTest.java b/1.0.0/modules/http/test/org/apache/axis2/transport/http/SimpleHTTPServerTest.java
new file mode 100644
index 0000000..7613ec1
--- /dev/null
+++ b/1.0.0/modules/http/test/org/apache/axis2/transport/http/SimpleHTTPServerTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.axis2.transport.http;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.axis2.transport.testkit.ManagedTestSuite;
+import org.apache.axis2.transport.testkit.axis2.TransportDescriptionFactory;
+import org.apache.axis2.transport.testkit.http.HttpTransportTestSuiteBuilder;
+
+public class SimpleHTTPServerTest extends TestCase {
+ public static TestSuite suite() throws Exception {
+ ManagedTestSuite suite = new ManagedTestSuite(SimpleHTTPServerTest.class);
+
+ TransportDescriptionFactory tdf = new HttpTransportDescriptionFactory(8280);
+
+ new HttpTransportTestSuiteBuilder(suite, tdf).build();
+
+ return suite;
+ }
+}
diff --git a/1.0.0/modules/jms/pom.xml b/1.0.0/modules/jms/pom.xml
new file mode 100644
index 0000000..64fefb1
--- /dev/null
+++ b/1.0.0/modules/jms/pom.xml
@@ -0,0 +1,204 @@
+<?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="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transports</artifactId>
+ <version>1.0.0</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-jms</artifactId>
+ <name>Apache Axis2 - Transport - JMS</name>
+ <description>Apache Axis2 - JMS Transport</description>
+ <packaging>bundle</packaging>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>../..</directory>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.0</version>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>generate-test-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <stripVersion>true</stripVersion>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjweaver</artifactId>
+ <outputDirectory>target/lib</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <systemProperties>
+ <property>
+ <name>log4j.configuration</name>
+ <value>file:../../log4j.properties</value>
+ </property>
+ </systemProperties>
+ <argLine>-javaagent:target/lib/aspectjweaver.jar -Xms64m -Xmx128m</argLine>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.4.0</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Version>1.0</Bundle-Version>
+ <Bundle-Name>${pom.artifactId}</Bundle-Name>
+ <Bundle-Vendor>Apache Software Foundation</Bundle-Vendor>
+ <Bundle-Description>${pom.description}</Bundle-Description>
+ <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+ <Export-Package>
+ org.apache.axis2.transport.jms.*;-split-package:=merge-last,
+ </Export-Package>
+ <Import-Package>
+ !javax.xml.namespace,
+ javax.xml.namespace; version=0.0.0,
+ *; resolution:=optional
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-base</artifactId>
+ <version>${version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.axis2</groupId>
+ <artifactId>axis2-transport-testkit</artifactId>
+ <version>${pom.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockejb</groupId>
+ <artifactId>mockejb</artifactId>
+ <version>0.6-beta2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid-broker</artifactId>
+ <version>1.0-incubating-M2.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid-client</artifactId>
+ <version>1.0-incubating-M2.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>activemq-core</artifactId>
+ <version>5.1.0</version>
+ <scope>test</scope>
+ <exclusions>
+ <!-- We want to choose the JAF implementation ourselves -->
+ <exclusion>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jms_1.1_spec</artifactId>
+ <version>${jms-1.1-spec.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jta_1.0.1B_spec</artifactId>
+ <version>${jta-spec.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockejb</groupId>
+ <artifactId>mockejb</artifactId>
+ <version>0.6-beta2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <!-- this is for qpid -->
+ <repository>
+ <id>apache-incubating</id>
+ <name>Apache Maven 2 Incubating Repository</name>
+ <url>http://people.apache.org/repo/m2-incubating-repository/</url>
+ <releases>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <updatePolicy>interval:60</updatePolicy>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <properties>
+ <jms-1.1-spec.version>1.1</jms-1.1-spec.version>
+ <jta-spec.version>1.0</jta-spec.version>
+ </properties>
+
+</project>
\ No newline at end of file
diff --git a/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/AxisJMSException.java b/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/AxisJMSException.java
new file mode 100644
index 0000000..0a98b14
--- /dev/null
+++ b/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/AxisJMSException.java
@@ -0,0 +1,32 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* 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.
+*/
+package org.apache.axis2.transport.jms;
+
+public class AxisJMSException extends RuntimeException {
+ private static final long serialVersionUID = 630157137524249401L;
+
+ AxisJMSException() {
+ super();
+ }
+
+ AxisJMSException(String msg) {
+ super(msg);
+ }
+
+ AxisJMSException(String msg, Exception e) {
+ super(msg, e);
+ }
+}
diff --git a/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConnectionFactory.java b/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConnectionFactory.java
new file mode 100644
index 0000000..250f389
--- /dev/null
+++ b/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConnectionFactory.java
@@ -0,0 +1,406 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* 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.
+*/
+package org.apache.axis2.transport.jms;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.description.ParameterIncludeImpl;
+import org.apache.axis2.AxisFault;
+import org.apache.axiom.om.OMElement;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.util.Hashtable;
+
+/**
+ * Encapsulate a JMS Connection factory definition within an Axis2.xml
+ *
+ * JMS Connection Factory definitions, allows JNDI properties as well as other service
+ * level parameters to be defined, and re-used by each service that binds to it
+ *
+ * When used for sending messages out, the JMSConnectionFactory'ies are able to cache
+ * a Connection, Session or Producer
+ */
+public class JMSConnectionFactory {
+
+ private static final Log log = LogFactory.getLog(JMSConnectionFactory.class);
+
+ /** The name used for the connection factory definition within Axis2 */
+ private String name = null;
+ /** The list of parameters from the axis2.xml definition */
+ private Hashtable<String, String> parameters = new Hashtable<String, String>();
+
+ /** The cached InitialContext reference */
+ private Context context = null;
+ /** The JMS ConnectionFactory this definition refers to */
+ private ConnectionFactory conFactory = null;
+ /** The shared JMS Connection for this JMS connection factory */
+ private Connection sharedConnection = null;
+ /** The shared JMS Session for this JMS connection factory */
+ private Session sharedSession = null;
+ /** The shared JMS MessageProducer for this JMS connection factory */
+ private MessageProducer sharedProducer = null;
+ /** The Shared Destination */
+ private Destination sharedDestination = null;
+ /** The shared JMS connection for this JMS connection factory */
+ private int cacheLevel = JMSConstants.CACHE_CONNECTION;
+
+ /**
+ * Digest a JMS CF definition from an axis2.xml 'Parameter' and construct
+ * @param parameter the axis2.xml 'Parameter' that defined the JMS CF
+ */
+ public JMSConnectionFactory(Parameter parameter) {
+
+ this.name = parameter.getName();
+ ParameterIncludeImpl pi = new ParameterIncludeImpl();
+
+ try {
+ pi.deserializeParameters((OMElement) parameter.getValue());
+ } catch (AxisFault axisFault) {
+ handleException("Error reading parameters for JMS connection factory" + name, axisFault);
+ }
+
+ for (Object o : pi.getParameters()) {
+ Parameter p = (Parameter) o;
+ parameters.put(p.getName(), (String) p.getValue());
+ }
+
+ digestCacheLevel();
+ try {
+ context = new InitialContext(parameters);
+ conFactory = JMSUtils.lookup(context, ConnectionFactory.class,
+ parameters.get(JMSConstants.PARAM_CONFAC_JNDI_NAME));
+ if (parameters.get(JMSConstants.PARAM_DESTINATION) != null) {
+ sharedDestination = JMSUtils.lookup(context, Destination.class,
+ parameters.get(JMSConstants.PARAM_DESTINATION));
+ }
+ log.info("JMS ConnectionFactory : " + name + " initialized");
+
+ } catch (NamingException e) {
+ throw new AxisJMSException("Cannot acquire JNDI context, JMS Connection factory : " +
+ parameters.get(JMSConstants.PARAM_CONFAC_JNDI_NAME) + " or default destination : " +
+ parameters.get(JMSConstants.PARAM_DESTINATION) +
+ " for JMS CF : " + name + " using : " + parameters, e);
+ }
+ }
+
+ /**
+ * Digest, the cache value iff specified
+ */
+ private void digestCacheLevel() {
+
+ String key = JMSConstants.PARAM_CACHE_LEVEL;
+ String val = parameters.get(key);
+
+ if ("none".equalsIgnoreCase(val)) {
+ this.cacheLevel = JMSConstants.CACHE_NONE;
+ } else if ("connection".equalsIgnoreCase(val)) {
+ this.cacheLevel = JMSConstants.CACHE_CONNECTION;
+ } else if ("session".equals(val)){
+ this.cacheLevel = JMSConstants.CACHE_SESSION;
+ } else if ("producer".equals(val)) {
+ this.cacheLevel = JMSConstants.CACHE_PRODUCER;
+ } else if (val != null) {
+ throw new AxisJMSException("Invalid cache level : " + val + " for JMS CF : " + name);
+ }
+ }
+
+ /**
+ * Return the name assigned to this JMS CF definition
+ * @return name of the JMS CF
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * The list of properties (including JNDI and non-JNDI)
+ * @return properties defined on the JMS CF
+ */
+ public Hashtable<String, String> getParameters() {
+ return parameters;
+ }
+
+ /**
+ * Get cached InitialContext
+ * @return cache InitialContext
+ */
+ public Context getContext() {
+ return context;
+ }
+
+ /**
+ * Cache level applicable for this JMS CF
+ * @return applicable cache level
+ */
+ public int getCacheLevel() {
+ return cacheLevel;
+ }
+
+ /**
+ * Get the shared Destination - if defined
+ * @return
+ */
+ public Destination getSharedDestination() {
+ return sharedDestination;
+ }
+
+ /**
+ * Lookup a Destination using this JMS CF definitions and JNDI name
+ * @param destinationName JNDI name of the Destionation
+ * @param destinationType looking up destination type
+ * @return JMS Destination for the given JNDI name or null
+ */
+ public Destination getDestination(String destinationName, String destinationType) {
+ try {
+ return JMSUtils.lookupDestination(context, destinationName, destinationType);
+ } catch (NamingException e) {
+ handleException("Error looking up the JMS destination with name " + destinationName
+ + " of type " + destinationType, e);
+ }
+
+ // never executes but keeps the compiler happy
+ return null;
+ }
+
+ /**
+ * Get the reply Destination from the PARAM_REPLY_DESTINATION parameter
+ * @return reply destination defined in the JMS CF
+ */
+ public String getReplyToDestination() {
+ return parameters.get(JMSConstants.PARAM_REPLY_DESTINATION);
+ }
+
+ /**
+ * Get the reply destination type from the PARAM_REPLY_DEST_TYPE parameter
+ * @return reply destination defined in the JMS CF
+ */
+ public String getReplyDestinationType() {
+ return parameters.get(JMSConstants.PARAM_REPLY_DEST_TYPE) != null ?
+ parameters.get(JMSConstants.PARAM_REPLY_DEST_TYPE) :
+ JMSConstants.DESTINATION_TYPE_GENERIC;
+ }
+
+ private void handleException(String msg, Exception e) {
+ log.error(msg, e);
+ throw new AxisJMSException(msg, e);
+ }
+
+ /**
+ * Should the JMS 1.1 API be used? - defaults to yes
+ * @return true, if JMS 1.1 api should be used
+ */
+ public boolean isJmsSpec11() {
+ return parameters.get(JMSConstants.PARAM_JMS_SPEC_VER) == null ||
+ "1.1".equals(parameters.get(JMSConstants.PARAM_JMS_SPEC_VER));
+ }
+
+ /**
+ * Return the type of the JMS CF Destination
+ * @return TRUE if a Queue, FALSE for a Topic and NULL for a JMS 1.1 Generic Destination
+ */
+ public Boolean isQueue() {
+ if (parameters.get(JMSConstants.PARAM_CONFAC_TYPE) == null &&
+ parameters.get(JMSConstants.PARAM_DEST_TYPE) == null) {
+ return null;
+ }
+
+ if (parameters.get(JMSConstants.PARAM_CONFAC_TYPE) != null) {
+ if ("queue".equalsIgnoreCase(parameters.get(JMSConstants.PARAM_CONFAC_TYPE))) {
+ return true;
+ } else if ("topic".equalsIgnoreCase(parameters.get(JMSConstants.PARAM_CONFAC_TYPE))) {
+ return false;
+ } else {
+ throw new AxisJMSException("Invalid " + JMSConstants.PARAM_CONFAC_TYPE + " : " +
+ parameters.get(JMSConstants.PARAM_CONFAC_TYPE) + " for JMS CF : " + name);
+ }
+ } else {
+ if ("queue".equalsIgnoreCase(parameters.get(JMSConstants.PARAM_DEST_TYPE))) {
+ return true;
+ } else if ("topic".equalsIgnoreCase(parameters.get(JMSConstants.PARAM_DEST_TYPE))) {
+ return false;
+ } else {
+ throw new AxisJMSException("Invalid " + JMSConstants.PARAM_DEST_TYPE + " : " +
+ parameters.get(JMSConstants.PARAM_DEST_TYPE) + " for JMS CF : " + name);
+ }
+ }
+ }
+
+ /**
+ * Is a session transaction requested from users of this JMS CF?
+ * @return session transaction required by the clients of this?
+ */
+ private boolean isSessionTransacted() {
+ return parameters.get(JMSConstants.PARAM_SESSION_TRANSACTED) == null ||
+ Boolean.valueOf(parameters.get(JMSConstants.PARAM_SESSION_TRANSACTED));
+ }
+
+ /**
+ * Create a new Connection
+ * @return a new Connection
+ */
+ private Connection createConnection() {
+
+ Connection connection = null;
+ try {
+ connection = JMSUtils.createConnection(
+ conFactory,
+ parameters.get(JMSConstants.PARAM_JMS_USERNAME),
+ parameters.get(JMSConstants.PARAM_JMS_PASSWORD),
+ isJmsSpec11(), isQueue());
+
+ if (log.isDebugEnabled()) {
+ log.debug("New JMS Connection from JMS CF : " + name + " created");
+ }
+
+ } catch (JMSException e) {
+ handleException("Error acquiring a Connection from the JMS CF : " + name +
+ " using properties : " + parameters, e);
+ }
+ return connection;
+ }
+
+ /**
+ * Create a new Session
+ * @param connection Connection to use
+ * @return A new Session
+ */
+ private Session createSession(Connection connection) {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Creating a new JMS Session from JMS CF : " + name);
+ }
+ return JMSUtils.createSession(
+ connection, isSessionTransacted(), Session.AUTO_ACKNOWLEDGE, isJmsSpec11(), isQueue());
+
+ } catch (JMSException e) {
+ handleException("Error creating JMS session from JMS CF : " + name, e);
+ }
+ return null;
+ }
+
+ /**
+ * Create a new MessageProducer
+ * @param session Session to be used
+ * @param destination Destination to be used
+ * @return a new MessageProducer
+ */
+ private MessageProducer createProducer(Session session, Destination destination) {
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Creating a new JMS MessageProducer from JMS CF : " + name);
+ }
+
+ return JMSUtils.createProducer(
+ session, destination, isQueue(), isJmsSpec11());
+
+ } catch (JMSException e) {
+ handleException("Error creating JMS producer from JMS CF : " + name,e);
+ }
+ return null;
+ }
+
+ /**
+ * Get a new Connection or shared Connection from this JMS CF
+ * @return new or shared Connection from this JMS CF
+ */
+ public Connection getConnection() {
+ if (cacheLevel > JMSConstants.CACHE_NONE) {
+ return getSharedConnection();
+ } else {
+ return createConnection();
+ }
+ }
+
+ /**
+ * Get a new Session or shared Session from this JMS CF
+ * @param connection the Connection to be used
+ * @return new or shared Session from this JMS CF
+ */
+ public Session getSession(Connection connection) {
+ if (cacheLevel > JMSConstants.CACHE_CONNECTION) {
+ return getSharedSession();
+ } else {
+ return createSession((connection == null ? getConnection() : connection));
+ }
+ }
+
+ /**
+ * Get a new MessageProducer or shared MessageProducer from this JMS CF
+ * @param connection the Connection to be used
+ * @param session the Session to be used
+ * @param destination the Destination to bind MessageProducer to
+ * @return new or shared MessageProducer from this JMS CF
+ */
+ public MessageProducer getMessageProducer(
+ Connection connection, Session session, Destination destination) {
+ if (cacheLevel > JMSConstants.CACHE_SESSION) {
+ return getSharedProducer();
+ } else {
+ return createProducer((session == null ? getSession(connection) : session), destination);
+ }
+ }
+
+ /**
+ * Get a new Connection or shared Connection from this JMS CF
+ * @return new or shared Connection from this JMS CF
+ */
+ private Connection getSharedConnection() {
+ if (sharedConnection == null) {
+ sharedConnection = createConnection();
+ if (log.isDebugEnabled()) {
+ log.debug("Created shared JMS Connection for JMS CF : " + name);
+ }
+ }
+ return sharedConnection;
+ }
+
+ /**
+ * Get a shared Session from this JMS CF
+ * @return shared Session from this JMS CF
+ */
+ private Session getSharedSession() {
+ if (sharedSession == null) {
+ sharedSession = createSession(getSharedConnection());
+ if (log.isDebugEnabled()) {
+ log.debug("Created shared JMS Session for JMS CF : " + name);
+ }
+ }
+ return sharedSession;
+ }
+
+ /**
+ * Get a shared MessageProducer from this JMS CF
+ * @return shared MessageProducer from this JMS CF
+ */
+ private MessageProducer getSharedProducer() {
+ if (sharedProducer == null) {
+ sharedProducer = createProducer(getSharedSession(), sharedDestination);
+ if (log.isDebugEnabled()) {
+ log.debug("Created shared JMS MessageConsumer for JMS CF : " + name);
+ }
+ }
+ return sharedProducer;
+ }
+}
diff --git a/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConnectionFactoryManager.java b/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConnectionFactoryManager.java
new file mode 100644
index 0000000..4c456b6
--- /dev/null
+++ b/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConnectionFactoryManager.java
@@ -0,0 +1,121 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* 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.
+*/
+package org.apache.axis2.transport.jms;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.Context;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.description.ParameterInclude;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Class managing a set of {@link JMSConnectionFactory} objects.
+ */
+public class JMSConnectionFactoryManager {
+
+ private static final Log log = LogFactory.getLog(JMSConnectionFactoryManager.class);
+
+ /** A Map containing the JMS connection factories managed by this, keyed by name */
+ private final Map<String,JMSConnectionFactory> connectionFactories =
+ new HashMap<String,JMSConnectionFactory>();
+
+ /**
+ * Construct a Connection factory manager for the JMS transport sender or receiver
+ * @param trpInDesc
+ */
+ public JMSConnectionFactoryManager(ParameterInclude trpInDesc) {
+ loadConnectionFactoryDefinitions(trpInDesc);
+ }
+
+ /**
+ * Create JMSConnectionFactory instances for the definitions in the transport configuration,
+ * and add these into our collection of connectionFactories map keyed by name
+ *
+ * @param trpDesc the transport description for JMS
+ */
+ private void loadConnectionFactoryDefinitions(ParameterInclude trpDesc) {
+
+ for (Parameter p : trpDesc.getParameters()) {
+ try {
+ JMSConnectionFactory jmsConFactory = new JMSConnectionFactory(p);
+ connectionFactories.put(jmsConFactory.getName(), jmsConFactory);
+ } catch (AxisJMSException e) {
+ log.error("Error setting up connection factory : " + p.getName(), e);
+ }
+ }
+ }
+
+ /**
+ * Get the JMS connection factory with the given name.
+ *
+ * @param name the name of the JMS connection factory
+ * @return the JMS connection factory or null if no connection factory with
+ * the given name exists
+ */
+ public JMSConnectionFactory getJMSConnectionFactory(String name) {
+ return connectionFactories.get(name);
+ }
+
+ /**
+ * Get the JMS connection factory that matches the given properties, i.e. referring to
+ * the same underlying connection factory. Used by the JMSSender to determine if already
+ * available resources should be used for outgoing messages
+ *
+ * @param props a Map of connection factory JNDI properties and name
+ * @return the JMS connection factory or null if no connection factory compatible
+ * with the given properties exists
+ */
+ public JMSConnectionFactory getJMSConnectionFactory(Map<String,String> props) {
+ for (JMSConnectionFactory cf : connectionFactories.values()) {
+ Map<String,String> cfProperties = cf.getParameters();
+
+ if (equals(props.get(JMSConstants.PARAM_CONFAC_JNDI_NAME),
+ cfProperties.get(JMSConstants.PARAM_CONFAC_JNDI_NAME))
+ &&
+ equals(props.get(Context.INITIAL_CONTEXT_FACTORY),
+ cfProperties.get(Context.INITIAL_CONTEXT_FACTORY))
+ &&
+ equals(props.get(Context.PROVIDER_URL),
+ cfProperties.get(Context.PROVIDER_URL))
+ &&
+ equals(props.get(Context.SECURITY_PRINCIPAL),
+ cfProperties.get(Context.SECURITY_PRINCIPAL))
+ &&
+ equals(props.get(Context.SECURITY_CREDENTIALS),
+ cfProperties.get(Context.SECURITY_CREDENTIALS))) {
+ return cf;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Compare two values preventing NPEs
+ */
+ private static boolean equals(Object s1, Object s2) {
+ return s1 == s2 || s1 != null && s1.equals(s2);
+ }
+
+ protected void handleException(String msg, Exception e) throws AxisFault {
+ log.error(msg, e);
+ throw new AxisFault(msg, e);
+ }
+}
diff --git a/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConstants.java b/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConstants.java
new file mode 100644
index 0000000..a6c74cf
--- /dev/null
+++ b/1.0.0/modules/jms/src/main/java/org/apache/axis2/transport/jms/JMSConstants.java
@@ -0,0 +1,273 @@
+/*
+* Copyright 2004,2005 The Apache Software Foundation.
+*
+* 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.
+*/
+package org.apache.axis2.transport.jms;
+
+import org.apache.axis2.client.Options;
+
+public class JMSConstants {
+
+ /**
+ * The prefix indicating an Axis JMS URL
+ */
+ public static final String JMS_PREFIX = "jms:/";
+
+ //------------------------------------ defaults / constants ------------------------------------
+ /**
+ * The local (Axis2) JMS connection factory name of the default connection
+ * factory to be used, if a service does not explicitly state the connection
+ * factory it should be using by a Parameter named JMSConstants.CONFAC_PARAM
+ */
+ public static final String DEFAULT_CONFAC_NAME = "default";
+ /**
+ * The default JMS time out waiting for a reply - also see {@link JMS_WAIT_REPLY}
+ */
+ public static final long DEFAULT_JMS_TIMEOUT = Options.DEFAULT_TIMEOUT_MILLISECONDS;
+ /**
+ * Value indicating a Queue used for {@link DEST_PARAM_TYPE}, {@link REPLY_PARAM_TYPE}
+ */
+ public static final String DESTINATION_TYPE_QUEUE = "queue";
+ /**
+ * Value indicating a Topic used for {@link DEST_PARAM_TYPE}, {@link REPLY_PARAM_TYPE}
+ */
+ public static final String DESTINATION_TYPE_TOPIC = "topic";
+ /**
+ * Value indicating a JMS 1.1 Generic Destination used by {@link DEST_PARAM_TYPE}, {@link REPLY_PARAM_TYPE}
+ */
+ public static final String DESTINATION_TYPE_GENERIC = "generic";
+
+ /** Do not cache any JMS resources between tasks (when sending) or JMS CF's (when sending) */
+ public static final int CACHE_NONE = 0;
+ /** Cache only the JMS connection between tasks (when receiving), or JMS CF's (when sending)*/
+ public static final int CACHE_CONNECTION = 1;
+ /** Cache only the JMS connection and Session between tasks (receiving), or JMS CF's (sending) */
+ public static final int CACHE_SESSION = 2;
+ /** Cache the JMS connection, Session and Consumer between tasks when receiving*/
+ public static final int CACHE_CONSUMER = 3;
+ /** Cache the JMS connection, Session and Producer within a JMSConnectionFactory when sending */
+ public static final int CACHE_PRODUCER = 4;
+ /** automatic choice of an appropriate caching level (depending on the transaction strategy) */
+ public static final int CACHE_AUTO = 5;
+
+ /** A JMS 1.1 Generic Destination type or ConnectionFactory */
+ public static final int GENERIC = 0;
+ /** A Queue Destination type or ConnectionFactory */
+ public static final int QUEUE = 1;
+ /** A Topic Destination type or ConnectionFactory */
+ public static final int TOPIC = 2;
+
+ /**
+ * The EPR parameter name indicating the name of the message level property that indicated the content type.
+ */
+ public static final String CONTENT_TYPE_PROPERTY_PARAM = "transport.jms.ContentTypeProperty";
+
+ //---------------------------------- services.xml parameters -----------------------------------
+ /**
+ * The Service level Parameter name indicating the JMS destination for requests of a service
+ */
+ public static final String PARAM_DESTINATION = "transport.jms.Destination";
+ /**
+ * The Service level Parameter name indicating the destination type for requests.
+ * also see {@link DESTINATION_TYPE_QUEUE}, {@link DESTINATION_TYPE_TOPIC}
+ */
+ public static final String PARAM_DEST_TYPE = "transport.jms.DestinationType";
+ /**
+ * The Service level Parameter name indicating the [default] response destination of a service
+ */
+ public static final String PARAM_REPLY_DESTINATION = "transport.jms.ReplyDestination";
+ /**
+ * The Service level Parameter name indicating the response destination type
+ * also see {@link DESTINATION_TYPE_QUEUE}, {@link DESTINATION_TYPE_TOPIC}
+ */
+ public static final String PARAM_REPLY_DEST_TYPE = "transport.jms.ReplyDestinationType";
+ /**
+ * The Parameter name of an Axis2 service, indicating the JMS connection
+ * factory which should be used to listen for messages for it. This is
+ * the local (Axis2) name of the connection factory and not the JNDI name
+ */
+ public static final String PARAM_JMS_CONFAC = "transport.jms.ConnectionFactory";
+ /**
+ * Connection factory type if using JMS 1.0, either DESTINATION_TYPE_QUEUE or DESTINATION_TYPE_TOPIC
+ */
+ public static final String PARAM_CONFAC_TYPE = "transport.jms.ConnectionFactoryType";
+ /**
+ * The Parameter name indicating the JMS connection factory JNDI name
+ */
+ public static final String PARAM_CONFAC_JNDI_NAME = "transport.jms.ConnectionFactoryJNDIName";
+ /**
+ * The Parameter indicating the expected content type for messages received by the service.
+ */
+ public static final String CONTENT_TYPE_PARAM = "transport.jms.ContentType";
+ /**
+ * The Parameter indicating a final EPR as a String, to be published on the WSDL of a service
+ * Could occur more than once, and could provide additional connection properties or a subset
+ * of the properties auto computed. Also could replace IP addresses with hostnames, and expose
+ * public credentials clients. If a user specified this parameter, the auto generated EPR will
+ * not be exposed - unless an instance of this parameter is added with the string "legacy"
+ * This parameter could be used to expose EPR's conforming to the proposed SOAP/JMS spec
+ * until such time full support is implemented for it.
+ */
+ public static final String PARAM_PUBLISH_EPR = "transport.jms.PublishEPR";
+ /** The parameter indicating the JMS API specification to be used - if this is "1.1" the JMS
+ * 1.1 API would be used, else the JMS 1.0.2B
+ */
+ public static final String PARAM_JMS_SPEC_VER = "transport.jms.JMSSpecVersion";
+
+ /**
+ * The Parameter indicating whether the JMS Session should be transacted for the service
+ * Specified as a "true" or "false"
+ */
+ public static final String PARAM_SESSION_TRANSACTED = "transport.jms.SessionTransacted";
+ /**
+ * The Parameter indicating the Session acknowledgement for the service. Must be one of the
+ * following Strings, or the appropriate Integer used by the JMS API
+ * "AUTO_ACKNOWLEDGE", "CLIENT_ACKNOWLEDGE", "DUPS_OK_ACKNOWLEDGE" or "SESSION_TRANSACTED"
+ */
+ public static final String PARAM_SESSION_ACK = "transport.jms.SessionAcknowledgement";
+ /** A message selector to be used when messages are sought for this service */
+ public static final String PARAM_MSG_SELECTOR = "transport.jms.MessageSelector";
+ /** Is the Subscription durable ? - "true" or "false" See {@link PARAM_DURABLE_SUB_NAME} */
+ public static final String PARAM_SUB_DURABLE = "transport.jms.SubscriptionDurable";
+ /** The name for the durable subscription See {@link PARAM_SUB_DURABLE}*/
+ public static final String PARAM_DURABLE_SUB_NAME = "transport.jms.DurableSubscriberName";
+ /**
+ * JMS Resource cachable level to be used for the service One of the following:
+ * {@link CACHE_NONE}, {@link CACHE_CONNECTION}, {@link CACHE_SESSION}, {@link CACHE_PRODUCER},
+ * {@link CACHE_CONSUMER}, or {@link CACHE_AUTO} - to let the transport decide
+ */
+ public static final String PARAM_CACHE_LEVEL = "transport.jms.CacheLevel";
+ /** Should a pub-sub connection receive messages published by itself? */
+ public static final String PARAM_PUBSUB_NO_LOCAL = "transport.jms.PubSubNoLocal";
+ /**
+ * The number of milliseconds to wait for a message on a consumer.receive() call
+ * negative number - wait forever
+ * 0 - do not wait at all
+ * positive number - indicates the number of milliseconds to wait
+ */
+ public static final String PARAM_RCV_TIMEOUT = "transport.jms.ReceiveTimeout";
+ /**
+ *The number of concurrent consumers to be created to poll for messages for this service
+ * For Topics, this should be ONE, to prevent receipt of multiple copies of the same message
+ */
+ public static final String PARAM_CONCURRENT_CONSUMERS = "transport.jms.ConcurrentConsumers";
+ /**
+ * The maximum number of concurrent consumers for the service - See {@link PARAM_CONCURRENT_CONSUMERS}
+ */
+ public static final String PARAM_MAX_CONSUMERS = "transport.jms.MaxConcurrentConsumers";
... 30267 lines suppressed ...