JAMES-2138 move MailAddress to a new james-core project move james.core package to james.server.core to avoid conflict
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/936746b9 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/936746b9 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/936746b9 Branch: refs/heads/master Commit: 936746b9a8c85fbe2c303baedfdb7a067813f633 Parents: e9cb6e9 Author: Matthieu Baechler <matth...@apache.org> Authored: Mon Sep 4 17:03:41 2017 +0200 Committer: benwa <btell...@linagora.com> Committed: Sat Sep 9 10:46:01 2017 +0700 ---------------------------------------------------------------------- core/pom.xml | 65 ++ .../java/org/apache/james/core/MailAddress.java | 623 ++++++++++++++++ .../org/apache/james/core/MailAddressTest.java | 229 ++++++ .../james/ai/classic/BayesianAnalysis.java | 2 +- mailet/api/pom.xml | 4 + .../src/main/java/org/apache/mailet/Mail.java | 1 + .../java/org/apache/mailet/MailAddress.java | 550 +-------------- .../java/org/apache/mailet/MailetContext.java | 1 + .../main/java/org/apache/mailet/Matcher.java | 2 + .../org/apache/mailet/PerRecipientHeaders.java | 2 + .../java/org/apache/mailet/MailAddressTest.java | 229 ------ .../base/AutomaticallySentMailDetectorImpl.java | 2 +- .../org/apache/mailet/base/GenericMatcher.java | 2 +- .../mailet/base/GenericRecipientMatcher.java | 2 +- .../org/apache/mailet/base/MatcherInverter.java | 2 +- .../AutomaticallySentMailDetectorImplTest.java | 2 +- .../apache/mailet/base/MailAddressFixture.java | 2 +- .../apache/mailet/base/MatcherInverterTest.java | 2 +- .../org/apache/mailet/base/test/FakeMail.java | 2 +- .../mailet/base/test/FakeMailContext.java | 2 +- .../org/apache/mailet/base/test/MailUtil.java | 2 +- .../james/transport/mailets/AbstractSign.java | 2 +- .../transport/matcher/IsSMIMEEncrypted.java | 2 +- .../james/transport/matcher/IsSMIMESigned.java | 2 +- .../matcher/IsX509CertificateSubject.java | 2 +- .../transport/mailets/ICALToJsonAttribute.java | 2 +- .../james/transport/mailets/model/ICAL.java | 2 +- .../mailets/ICALToJsonAttributeTest.java | 2 +- .../james/transport/mailets/model/ICALTest.java | 2 +- .../transport/mailets/AddDeliveredToHeader.java | 2 +- .../james/transport/mailets/ClamAVScan.java | 2 +- .../transport/mailets/PostmasterAlias.java | 2 +- .../transport/mailets/RecipientToLowerCase.java | 2 +- .../transport/mailets/UseHeaderRecipients.java | 2 +- .../matchers/AbstractQuotaMatcher.java | 2 +- .../apache/james/transport/matchers/All.java | 2 +- .../matchers/AttachmentFileNameIs.java | 2 +- .../transport/matchers/CommandForListserv.java | 2 +- .../matchers/CommandListservMatcher.java | 2 +- .../matchers/CompareNumericHeaderValue.java | 2 +- .../james/transport/matchers/FetchedFrom.java | 2 +- .../transport/matchers/GenericRegexMatcher.java | 2 +- .../james/transport/matchers/HasAttachment.java | 2 +- .../matchers/HasHabeasWarrantMark.java | 2 +- .../james/transport/matchers/HasHeader.java | 2 +- .../transport/matchers/HasHeaderWithPrefix.java | 2 +- .../transport/matchers/HasMailAttribute.java | 2 +- .../matchers/HasMailAttributeWithValue.java | 2 +- .../HasMailAttributeWithValueRegex.java | 2 +- .../apache/james/transport/matchers/HostIs.java | 2 +- .../james/transport/matchers/HostIsLocal.java | 2 +- .../transport/matchers/IsSingleRecipient.java | 2 +- .../james/transport/matchers/RecipientIs.java | 2 +- .../transport/matchers/RecipientIsLocal.java | 2 +- .../transport/matchers/RecipientIsRegex.java | 2 +- .../james/transport/matchers/RelayLimit.java | 2 +- .../transport/matchers/SMTPAuthSuccessful.java | 2 +- .../transport/matchers/SMTPAuthUserIs.java | 2 +- .../transport/matchers/SMTPIsAuthNetwork.java | 2 +- .../james/transport/matchers/SenderHostIs.java | 2 +- .../transport/matchers/SenderHostIsLocal.java | 2 +- .../james/transport/matchers/SenderIs.java | 2 +- .../james/transport/matchers/SenderIsLocal.java | 2 +- .../james/transport/matchers/SenderIsNull.java | 2 +- .../james/transport/matchers/SenderIsRegex.java | 2 +- .../james/transport/matchers/SentByMailet.java | 2 +- .../transport/matchers/SizeGreaterThan.java | 2 +- .../james/transport/matchers/SubjectIs.java | 2 +- .../transport/matchers/SubjectStartsWith.java | 2 +- .../james/transport/matchers/TooManyLines.java | 2 +- .../transport/matchers/TooManyRecipients.java | 2 +- .../apache/james/transport/matchers/UserIs.java | 2 +- .../utils/MailAddressCollectionReader.java | 2 +- .../james/transport/mailets/LogMessageTest.java | 2 +- .../mailets/RecipientToLowerCaseTest.java | 2 +- .../transport/mailets/ToProcessorTest.java | 2 +- .../mailets/UseHeaderRecipientsTest.java | 2 +- .../matchers/AbstractHasMailAttributeTest.java | 2 +- .../HasMailAttributeWithValueRegexTest.java | 2 +- .../matchers/HasMailAttributeWithValueTest.java | 2 +- .../matchers/RecipientIsLocalTest.java | 2 +- .../matchers/SMTPAuthSuccessfulTest.java | 2 +- .../transport/matchers/SMTPAuthUserIsTest.java | 3 +- .../matchers/SMTPIsAuthNetworkTest.java | 2 +- .../matchers/SenderHostIsLocalTest.java | 2 +- .../transport/matchers/SenderHostIsTest.java | 2 +- .../transport/matchers/SenderIsLocalTest.java | 2 +- .../transport/matchers/SenderIsNullTest.java | 2 +- .../transport/matchers/SenderIsRegexTest.java | 2 +- .../james/transport/matchers/SenderIsTest.java | 2 +- .../transport/matchers/SentByMailetTest.java | 2 +- .../james/transport/matchers/SubjectIsTest.java | 2 +- .../matchers/SubjectStartsWithTest.java | 2 +- .../transport/matchers/TooManyLinesTest.java | 2 +- .../matchers/TooManyRecipientsTest.java | 2 +- .../util/MailAddressCollectionReaderTest.java | 2 +- pom.xml | 6 + .../lmtp/core/DataLineMessageHookHandler.java | 2 +- .../lmtp/hook/DeliverToRecipientHook.java | 2 +- .../protocols/lmtp/AbstractLMTPServerTest.java | 2 +- protocols/pom.xml | 5 + protocols/smtp/pom.xml | 5 +- .../james/protocols/smtp/MailAddress.java | 469 +----------- .../protocols/smtp/MailAddressException.java | 12 +- .../james/protocols/smtp/MailEnvelope.java | 2 + .../james/protocols/smtp/MailEnvelopeImpl.java | 2 + .../james/protocols/smtp/SMTPSessionImpl.java | 1 + .../AbstractAuthRequiredToRelayRcptHook.java | 2 +- ...tSenderAuthIdentifyVerificationRcptHook.java | 2 +- .../AcceptRecipientIfRelayingIsAllowed.java | 2 +- .../protocols/smtp/core/DataCmdHandler.java | 3 +- .../protocols/smtp/core/MailCmdHandler.java | 2 +- .../smtp/core/PostmasterAbuseRcptHook.java | 2 +- .../protocols/smtp/core/RcptCmdHandler.java | 2 +- .../smtp/core/ReceivedDataLineFilter.java | 2 +- .../core/fastfail/AbstractGreylistHandler.java | 2 +- .../core/fastfail/AbstractValidRcptHandler.java | 6 +- .../smtp/core/fastfail/DNSRBLHandler.java | 2 +- .../smtp/core/fastfail/MaxRcptHandler.java | 2 +- .../fastfail/ResolvableEhloHeloHandler.java | 3 +- .../smtp/core/fastfail/SpamTrapHandler.java | 2 +- .../fastfail/SupressDuplicateRcptHandler.java | 6 +- .../core/fastfail/ValidSenderDomainHandler.java | 2 +- .../james/protocols/smtp/hook/MailHook.java | 6 +- .../james/protocols/smtp/hook/RcptHook.java | 2 +- .../james/protocols/smtp/hook/SimpleHook.java | 26 +- .../protocols/smtp/AbstractSMTPServerTest.java | 1 + .../smtp/core/fastfail/DNSRBLHandlerTest.java | 15 +- .../smtp/core/fastfail/MaxRcptHandlerTest.java | 7 +- .../core/fastfail/MaxUnknownCmdHandlerTest.java | 3 +- .../fastfail/ResolvableEhloHeloHandlerTest.java | 11 +- .../smtp/core/fastfail/SpamTrapHandlerTest.java | 6 +- .../fastfail/ValidSenderDomainHandlerTest.java | 5 +- .../james/core/InternetHeadersInputStream.java | 93 --- .../james/core/JamesServerResourceLoader.java | 72 -- .../java/org/apache/james/core/MailHeaders.java | 187 ----- .../java/org/apache/james/core/MailImpl.java | 691 ------------------ .../james/core/MimeMessageCopyOnWriteProxy.java | 561 --------------- .../james/core/MimeMessageInputStream.java | 127 ---- .../core/MimeMessageInputStreamSource.java | 174 ----- .../apache/james/core/MimeMessageSource.java | 84 --- .../org/apache/james/core/MimeMessageUtil.java | 311 -------- .../apache/james/core/MimeMessageWrapper.java | 705 ------------------- .../core/filesystem/ClassPathResource.java | 110 --- .../james/core/filesystem/FileSystemImpl.java | 60 -- .../core/filesystem/FileSystemResource.java | 44 -- .../apache/james/core/filesystem/Resource.java | 29 - .../james/core/filesystem/ResourceFactory.java | 100 --- .../james/core/filesystem/ResourceUtils.java | 41 -- .../apache/james/core/filesystem/SimpleUrl.java | 74 -- .../james/core/filesystem/UrlResource.java | 59 -- .../java/org/apache/james/core/package.html | 21 - .../server/core/InternetHeadersInputStream.java | 93 +++ .../server/core/JamesServerResourceLoader.java | 72 ++ .../apache/james/server/core/MailHeaders.java | 187 +++++ .../org/apache/james/server/core/MailImpl.java | 691 ++++++++++++++++++ .../core/MimeMessageCopyOnWriteProxy.java | 561 +++++++++++++++ .../server/core/MimeMessageInputStream.java | 127 ++++ .../core/MimeMessageInputStreamSource.java | 174 +++++ .../james/server/core/MimeMessageSource.java | 84 +++ .../james/server/core/MimeMessageUtil.java | 311 ++++++++ .../james/server/core/MimeMessageWrapper.java | 705 +++++++++++++++++++ .../core/filesystem/ClassPathResource.java | 110 +++ .../server/core/filesystem/FileSystemImpl.java | 60 ++ .../core/filesystem/FileSystemResource.java | 44 ++ .../james/server/core/filesystem/Resource.java | 29 + .../server/core/filesystem/ResourceFactory.java | 100 +++ .../server/core/filesystem/ResourceUtils.java | 41 ++ .../james/server/core/filesystem/SimpleUrl.java | 74 ++ .../server/core/filesystem/UrlResource.java | 59 ++ .../org/apache/james/server/core/package.html | 21 + .../org/apache/james/core/MailHeadersTest.java | 43 -- .../org/apache/james/core/MailImplTest.java | 115 --- .../james/core/MailTestAllImplementations.java | 72 -- .../core/MimeMessageCopyOnWriteProxyTest.java | 279 -------- .../core/MimeMessageFromMimeMessageTest.java | 31 - .../core/MimeMessageFromSharedStreamTest.java | 36 - .../james/core/MimeMessageFromStreamTest.java | 59 -- .../core/MimeMessageInputStreamSourceTest.java | 60 -- .../org/apache/james/core/MimeMessageTest.java | 437 ------------ .../apache/james/core/MimeMessageUtilTest.java | 65 -- .../james/core/MimeMessageWrapperTest.java | 289 -------- .../core/filesystem/FileSystemImplTest.java | 32 - .../james/core/filesystem/SimpleUrlTest.java | 114 --- .../james/server/core/MailHeadersTest.java | 43 ++ .../apache/james/server/core/MailImplTest.java | 115 +++ .../server/core/MailTestAllImplementations.java | 72 ++ .../core/MimeMessageCopyOnWriteProxyTest.java | 279 ++++++++ .../core/MimeMessageFromMimeMessageTest.java | 31 + .../core/MimeMessageFromSharedStreamTest.java | 36 + .../server/core/MimeMessageFromStreamTest.java | 59 ++ .../core/MimeMessageInputStreamSourceTest.java | 60 ++ .../james/server/core/MimeMessageTest.java | 437 ++++++++++++ .../james/server/core/MimeMessageUtilTest.java | 65 ++ .../server/core/MimeMessageWrapperTest.java | 289 ++++++++ .../core/filesystem/FileSystemImplTest.java | 32 + .../server/core/filesystem/SimpleUrlTest.java | 114 +++ .../com/custom/matchers/AnotherMatcher.java | 2 +- .../james/transport/matchers/CustomMatcher.java | 2 +- .../james/modules/CommonServicesModule.java | 4 +- .../james/modules/TestFilesystemModule.java | 2 +- .../utils/FileConfigurationProviderTest.java | 4 +- .../utils/InMemoryMailRepositoryStoreTest.java | 4 +- .../modules/server/MemoryMailQueueFactory.java | 2 +- .../context/JamesServerApplicationContext.java | 2 +- .../container/spring/tool/James23Importer.java | 2 +- .../spring/filesystem/FileSystemImplTest.java | 2 +- .../apache/james/user/api/UsersRepository.java | 2 +- .../apache/james/user/api/model/JamesUser.java | 2 +- .../mailrepository/file/FileMailRepository.java | 4 +- .../mailrepository/file/MBoxMailRepository.java | 2 +- .../file/MimeMessageStreamRepositorySource.java | 4 +- .../mailrepository/jcr/JCRMailRepository.java | 4 +- .../mailrepository/jdbc/JDBCMailRepository.java | 8 +- .../mailrepository/jdbc/MessageInputStream.java | 6 +- .../jdbc/MimeMessageJDBCSource.java | 6 +- .../user/jdbc/JamesUsersJdbcRepository.java | 2 +- .../james/jmap/api/vacation/RecipientId.java | 2 +- .../AbstractNotificationRegistryTest.java | 2 +- .../ldap/ReadOnlyUsersLDAPRepositoryTest.java | 2 +- .../user/ldap/ReadOnlyUsersLDAPRepository.java | 2 +- .../rrt/lib/AbstractRecipientRewriteTable.java | 2 +- .../rrt/lib/RecipientRewriteTableUtil.java | 2 +- .../james/user/lib/AbstractUsersRepository.java | 2 +- .../james/user/lib/model/DefaultJamesUser.java | 4 +- .../AbstractMailRepositoryTest.java | 8 +- .../user/lib/AbstractUsersRepositoryTest.java | 2 +- .../mailets/TemporaryFilesystemModule.java | 2 +- .../mailets/AmqpForwardAttachmentTest.java | 2 +- .../mailets/ICSAttachmentWorkflowTest.java | 2 +- .../transport/mailets/StripAttachmentTest.java | 2 +- .../api/mock/ExceptionThrowingMatcher.java | 2 +- .../api/mock/MockMailetContext.java | 2 +- .../mailetcontainer/api/mock/MockMatcher.java | 2 +- .../impl/JamesMailetContext.java | 4 +- .../mailetcontainer/impl/ProcessorUtil.java | 2 +- .../impl/camel/MatcherSplitter.java | 4 +- .../jmx/JMXStateMailetProcessorListener.java | 2 +- .../mailetcontainer/impl/matchers/And.java | 2 +- .../mailetcontainer/impl/matchers/Not.java | 2 +- .../james/mailetcontainer/impl/matchers/Or.java | 2 +- .../mailetcontainer/impl/matchers/Xor.java | 2 +- .../lib/AbstractStateMailetProcessor.java | 2 +- .../impl/JamesMailetContextTest.java | 2 +- .../mailetcontainer/impl/matchers/AndTest.java | 2 +- .../mailetcontainer/impl/matchers/NotTest.java | 2 +- .../mailetcontainer/impl/matchers/OrTest.java | 2 +- .../mailetcontainer/impl/matchers/XorTest.java | 2 +- .../AbstractStateCompositeProcessorTest.java | 2 +- .../lib/AbstractStateMailetProcessorTest.java | 4 +- .../mailets/AbstractRecipientRewriteTable.java | 4 +- .../transport/mailets/BayesianAnalysis.java | 2 +- .../apache/james/transport/mailets/Bounce.java | 2 +- .../james/transport/mailets/DSNBounce.java | 4 +- .../apache/james/transport/mailets/Forward.java | 2 +- .../james/transport/mailets/JDBCAlias.java | 2 +- .../mailets/JDBCRecipientRewriteTable.java | 2 +- .../transport/mailets/NotifyPostmaster.java | 2 +- .../james/transport/mailets/NotifySender.java | 2 +- .../mailets/RecipientRewriteTableProcessor.java | 2 +- .../james/transport/mailets/Redirect.java | 2 +- .../james/transport/mailets/RemoteDelivery.java | 2 +- .../apache/james/transport/mailets/Resend.java | 2 +- .../org/apache/james/transport/mailets/SPF.java | 2 +- .../apache/james/transport/mailets/Sieve.java | 2 +- .../james/transport/mailets/ToSenderFolder.java | 2 +- .../transport/mailets/WhiteListManager.java | 2 +- .../mailets/XMLRecipientRewriteTable.java | 2 +- .../mailets/delivery/DeliveryUtils.java | 2 +- .../mailets/delivery/MailDispatcher.java | 2 +- .../transport/mailets/delivery/MailStore.java | 2 +- .../mailets/delivery/MailboxAppender.java | 2 +- .../mailets/delivery/SimpleMailStore.java | 2 +- .../transport/mailets/jsieve/ActionContext.java | 2 +- .../transport/mailets/jsieve/ActionUtils.java | 2 +- .../mailets/jsieve/FileIntoAction.java | 2 +- .../mailets/jsieve/RedirectAction.java | 2 +- .../transport/mailets/jsieve/RejectAction.java | 2 +- .../mailets/jsieve/ResourceLocator.java | 2 +- .../mailets/jsieve/SieveMailAdapter.java | 2 +- .../mailets/jsieve/VacationAction.java | 2 +- .../transport/mailets/jsieve/VacationReply.java | 2 +- .../mailets/jsieve/delivery/SieveExecutor.java | 2 +- .../mailets/jsieve/delivery/SievePoster.java | 2 +- .../mailets/redirect/AddressExtractor.java | 2 +- .../redirect/MailMessageAlteringUtils.java | 2 +- .../mailets/redirect/MailModifier.java | 4 +- .../mailets/redirect/NotifyMailetsMessage.java | 2 +- .../mailets/redirect/ProcessRedirectNotify.java | 2 +- .../mailets/redirect/RedirectNotify.java | 2 +- .../mailets/redirect/SpecialAddress.java | 2 +- ...ddressesArrayToMailAddressListConverter.java | 2 +- .../mailets/remoteDelivery/Bouncer.java | 2 +- .../InternetAddressConverter.java | 2 +- .../mailets/remoteDelivery/MailDelivrer.java | 2 +- .../matchers/AbstractSQLWhitelistMatcher.java | 2 +- .../matchers/AbstractStorageQuota.java | 2 +- .../transport/matchers/InSpammerBlacklist.java | 2 +- .../james/transport/matchers/IsInWhiteList.java | 2 +- .../james/transport/matchers/IsOverQuota.java | 2 +- .../transport/matchers/MailboxQuotaFixed.java | 2 +- .../matchers/NetworkIsInWhitelist.java | 2 +- .../transport/matchers/RemoteAddrInNetwork.java | 2 +- .../matchers/RemoteAddrNotInNetwork.java | 2 +- .../transport/matchers/SenderInFakeDomain.java | 2 +- .../james/transport/util/MailAddressUtils.java | 2 +- .../james/transport/util/RecipientsUtils.java | 2 +- .../james/transport/util/ReplyToUtils.java | 2 +- .../james/transport/util/SenderUtils.java | 2 +- .../transport/util/SpecialAddressesUtils.java | 2 +- .../apache/james/transport/util/TosUtils.java | 2 +- .../samples/mailets/InstrumentationMailet.java | 2 +- .../james/transport/mailets/BounceTest.java | 2 +- .../james/transport/mailets/DSNBounceTest.java | 2 +- .../james/transport/mailets/ForwardTest.java | 2 +- .../transport/mailets/NotifyPostmasterTest.java | 2 +- .../transport/mailets/NotifySenderTest.java | 2 +- .../RecipientRewriteTableProcessorTest.java | 2 +- .../transport/mailets/RecordingMailContext.java | 2 +- .../james/transport/mailets/RedirectTest.java | 2 +- .../james/transport/mailets/ResendTest.java | 2 +- .../transport/mailets/ResourceLocatorTest.java | 2 +- .../mailets/delivery/LocalDeliveryTest.java | 2 +- .../mailets/delivery/MailDispatcherTest.java | 2 +- .../mailets/delivery/SieveIntegrationTest.java | 2 +- .../mailets/delivery/SimpleMailStoreTest.java | 2 +- .../mailets/delivery/ToRecipientFolderTest.java | 2 +- .../managesieve/ManageSieveMailetTestCase.java | 2 +- .../mailets/redirect/AddressExtractorTest.java | 2 +- .../mailets/redirect/MailModifierTest.java | 2 +- .../redirect/NotifyMailetsMessageTest.java | 2 +- .../mailets/redirect/SpecialAddressTest.java | 2 +- .../InternetAddressConverterTest.java | 2 +- .../matchers/InSpammerBlacklistTest.java | 2 +- .../transport/matchers/IsOverQuotaTest.java | 2 +- .../matchers/RemoteAddrInNetworkTest.java | 2 +- .../matchers/RemoteAddrNotInNetworkTest.java | 2 +- .../transport/util/MailAddressUtilsTest.java | 2 +- .../transport/util/RecipientsUtilsTest.java | 2 +- .../james/transport/util/ReplyToUtilsTest.java | 2 +- .../james/transport/util/SenderUtilsTest.java | 2 +- .../util/SpecialAddressesUtilsTest.java | 2 +- .../james/transport/util/TosUtilsTest.java | 2 +- .../org/apache/james/fetchmail/Account.java | 2 +- .../james/fetchmail/MessageProcessor.java | 4 +- .../james/fetchmail/ParsedConfiguration.java | 2 +- .../james/fetchmail/ProcessorAbstract.java | 2 +- .../james/jmap/UserProvisioningFilter.java | 2 +- .../apache/james/jmap/mailet/SentByJmap.java | 2 +- .../james/jmap/mailet/VacationMailet.java | 2 +- .../apache/james/jmap/mailet/VacationReply.java | 2 +- .../org/apache/james/jmap/send/MailFactory.java | 4 +- .../james/jmap/mailet/SentByJmapTest.java | 2 +- .../james/jmap/mailet/VacationMailetTest.java | 2 +- .../james/jmap/mailet/VacationReplyTest.java | 2 +- .../apache/james/jmap/send/MailFactoryTest.java | 2 +- .../james/lmtpserver/DataLineLMTPHandler.java | 9 +- .../hook/MailboxDeliverToRecipientHandler.java | 2 +- .../AddDefaultAttributesMessageHook.java | 2 +- .../DataLineJamesMessageHookHandler.java | 25 +- .../james/smtpserver/JamesDataCmdHandler.java | 4 +- .../james/smtpserver/MailPriorityHandler.java | 2 +- .../james/smtpserver/SendMailHandler.java | 2 +- .../SenderAuthIdentifyVerificationRcptHook.java | 2 +- .../fastfail/JDBCGreylistHandler.java | 2 +- .../james/smtpserver/fastfail/SPFHandler.java | 2 +- .../smtpserver/fastfail/ValidRcptHandler.java | 2 +- .../james/smtpserver/fastfail/ValidRcptMX.java | 2 +- .../model/MailetMailAddressAdapter.java | 4 +- .../model/ProtocolMailAddressAdapter.java | 10 +- .../apache/james/smtpserver/SMTPServerTest.java | 2 +- .../apache/james/smtpserver/SPFHandlerTest.java | 2 +- .../java/org/apache/james/smtpserver/Util.java | 2 +- .../james/smtpserver/ValidRcptHandlerTest.java | 2 +- .../james/smtpserver/ValidRcptMXTest.java | 7 +- .../james/smtpserver/mock/mailet/MockMail.java | 2 +- .../smtpserver/mock/mailet/MockMailContext.java | 2 +- .../WebAdminServerIntegrationTest.java | 2 + server/protocols/webadmin/webadmin-data/pom.xml | 4 + .../james/queue/activemq/ActiveMQMailQueue.java | 6 +- .../activemq/MimeMessageBlobMessageSource.java | 6 +- .../james/queue/api/mock/MockMailQueue.java | 2 +- .../apache/james/queue/file/FileMailQueue.java | 4 +- .../apache/james/queue/jms/JMSMailQueue.java | 6 +- .../jms/MimeMessageObjectMessageSource.java | 2 +- .../queue/library/MailQueueManagement.java | 2 +- .../queue/jms/AbstractJMSMailQueueTest.java | 21 +- 387 files changed, 6541 insertions(+), 6832 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/core/pom.xml ---------------------------------------------------------------------- diff --git a/core/pom.xml b/core/pom.xml new file mode 100644 index 0000000..388652b --- /dev/null +++ b/core/pom.xml @@ -0,0 +1,65 @@ +<?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/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>james-project</artifactId> + <groupId>org.apache.james</groupId> + <version>3.1.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>james-core</artifactId> + + <name>Apache James :: Core Domain Objects</name> + <description>Provides core domain objects for Email concepts</description> + + <dependencies> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-util-java8</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>nl.jqno.equalsverifier</groupId> + <artifactId>equalsverifier</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/core/src/main/java/org/apache/james/core/MailAddress.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/james/core/MailAddress.java b/core/src/main/java/org/apache/james/core/MailAddress.java new file mode 100644 index 0000000..54a0f49 --- /dev/null +++ b/core/src/main/java/org/apache/james/core/MailAddress.java @@ -0,0 +1,623 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT 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.james.core; + +import java.util.Locale; + +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; + +/** + * A representation of an email address. + * <p/> + * <p>This class encapsulates functionality to access different + * parts of an email address without dealing with its parsing.</p> + * <p/> + * <p>A MailAddress is an address specified in the MAIL FROM and + * RCPT TO commands in SMTP sessions. These are either passed by + * an external server to the mailet-compliant SMTP server, or they + * are created programmatically by the mailet-compliant server to + * send to another (external) SMTP server. Mailets and matchers + * use the MailAddress for the purpose of evaluating the sender + * and recipient(s) of a message.</p> + * <p/> + * <p>MailAddress parses an email address as defined in RFC 821 + * (SMTP) p. 30 and 31 where addresses are defined in BNF convention. + * As the mailet API does not support the aged "SMTP-relayed mail" + * addressing protocol, this leaves all addresses to be a {@code <mailbox>}, + * as per the spec. + * <p/> + * <p>This class is a good way to validate email addresses as there are + * some valid addresses which would fail with a simpler approach + * to parsing address. It also removes the parsing burden from + * mailets and matchers that might not realize the flexibility of an + * SMTP address. For instance, "serge@home"@lokitech.com is a valid + * SMTP address (the quoted text serge@home is the local-part and + * lokitech.com is the domain). This means all current parsing to date + * is incorrect as we just find the first '@' and use that to separate + * local-part from domain.</p> + * <p/> + * <p>This parses an address as per the BNF specification for <mailbox> + * from RFC 821 on page 30 and 31, section 4.1.2. COMMAND SYNTAX. + * http://www.freesoft.org/CIE/RFC/821/15.htm</p> + * + * @version 1.0 + */ +public class MailAddress implements java.io.Serializable { + /** + * We hardcode the serialVersionUID + * This version (2779163542539434916L) retains compatibility back to + * Mailet version 1.2 (James 1.2) so that MailAddress will be + * deserializable and mail doesn't get lost after an upgrade. + */ + public static final long serialVersionUID = 2779163542539434916L; + + private final static char[] SPECIAL = + {'<', '>', '(', ')', '[', ']', '\\', '.', ',', ';', ':', '@', '\"'}; + + private static final MailAddress NULL_SENDER = new MailAddress() { + + @Override + public String getDomain() { + return ""; + } + + @Override + public String getLocalPart() { + return ""; + } + + @Override + public String toString() { + return ""; + } + + @Override + public boolean isNullSender() { + return true; + } + + }; + + + public static MailAddress nullSender() { + return NULL_SENDER; + } + + private String localPart = null; + private String domain = null; + + private MailAddress() { + + } + + /** + * Strips source routing. According to RFC-2821 it is a valid approach + * to handle mails containing RFC-821 source-route information. + * + * @param address the address to strip + * @param pos current position + * @return new pos + */ + private int stripSourceRoute(String address, int pos) { + if (pos < address.length()) { + if (address.charAt(pos) == '@') { + int i = address.indexOf(':'); + if (i != -1) { + pos = i + 1; + } + } + } + return pos; + } + + /** + * Constructs a MailAddress by parsing the provided address. + * + * @param address the email address, compliant to the RFC2822 3.4.1. addr-spec specification + * @throws AddressException if the parse failed + */ + public MailAddress(String address) throws AddressException { + address = address.trim(); + int pos = 0; + + // Test if mail address has source routing information (RFC-821) and get rid of it!! + //must be called first!! (or at least prior to updating pos) + stripSourceRoute(address, pos); + + StringBuffer localPartSB = new StringBuffer(); + StringBuffer domainSB = new StringBuffer(); + //Begin parsing + //<mailbox> ::= <local-part> "@" <domain> + + try { + //parse local-part + //<local-part> ::= <dot-string> | <quoted-string> + if (address.charAt(pos) == '\"') { + pos = parseQuotedLocalPartOrThrowException(localPartSB, address, pos); + } else { + pos = parseUnquotedLocalPartOrThrowException(localPartSB, address, pos); + } + + //find @ + if (pos >= address.length() || address.charAt(pos) != '@') { + throw new AddressException("Did not find @ between local-part and domain at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + pos++; + + //parse domain + //<domain> ::= <element> | <element> "." <domain> + //<element> ::= <name> | "#" <number> | "[" <dotnum> "]" + while (true) { + if (address.charAt(pos) == '#') { + pos = parseNumber(domainSB, address, pos); + } else if (address.charAt(pos) == '[') { + pos = parseDomainLiteral(domainSB, address, pos); + } else { + pos = parseDomain(domainSB, address, pos); + } + if (pos >= address.length()) { + break; + } + if (address.charAt(pos) == '.') { + char lastChar = address.charAt(pos - 1); + if (lastChar == '@' || lastChar == '.') { + throw new AddressException("Subdomain expected before '.' or duplicate '.' in " + address); + } + domainSB.append('.'); + pos++; + continue; + } + break; + } + + if (domainSB.toString().length() == 0) { + throw new AddressException("No domain found at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + } catch (IndexOutOfBoundsException ioobe) { + throw new AddressException("Out of data at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + + localPart = localPartSB.toString(); + domain = domainSB.toString(); + } + + private int parseUnquotedLocalPartOrThrowException(StringBuffer localPartSB, String address, int pos) + throws AddressException { + pos = parseUnquotedLocalPart(localPartSB, address, pos); + if (localPartSB.toString().length() == 0) { + throw new AddressException("No local-part (user account) found at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + return pos; + } + + private int parseQuotedLocalPartOrThrowException(StringBuffer localPartSB, String address, int pos) + throws AddressException { + pos = parseQuotedLocalPart(localPartSB, address, pos); + if (localPartSB.toString().length() == 2) { + throw new AddressException("No quoted local-part (user account) found at position " + + (pos + 2) + " in '" + address + "'", address, pos + 2); + } + return pos; + } + + /** + * Constructs a MailAddress with the provided local part and domain. + * + * @param localPart the local-part portion. This is a domain dependent string. + * In addresses, it is simply interpreted on the particular host as a + * name of a particular mailbox. per RFC2822 3.4.1. addr-spec specification + * @param domain the domain portion. This identifies the point to which the mail + * is delivered per RFC2822 3.4.1. addr-spec specification + * @throws AddressException if the parse failed + */ + public MailAddress(String localPart, String domain) throws AddressException { + this(new InternetAddress(localPart + "@" + domain)); + } + + /** + * Constructs a MailAddress from an InternetAddress, using only the + * email address portion (an "addr-spec", not "name-addr", as + * defined in the RFC2822 3.4. Address Specification) + * + * @param address the address + * @throws AddressException if the parse failed + */ + public MailAddress(InternetAddress address) throws AddressException { + this(address.getAddress()); + } + + /** + * Returns the host part. + * + * @return the host part of this email address. If the host is of the + * dotNum form (e.g. [yyy.yyy.yyy.yyy]), then strip the braces first. + * @deprecated use {@link #getDomain()}, whose name was changed to + * align with RFC2822 3.4.1. addr-spec specification + */ + @Deprecated + public String getHost() { + return getDomain(); + } + + /** + * Returns the domain part per RFC2822 3.4.1. addr-spec specification. + * + * @return the domain part of this email address. If the domain is of + * the domain-literal form (e.g. [yyy.yyy.yyy.yyy]), the braces will + * have been stripped returning the raw IP address. + * @since Mailet API 2.4 + */ + public String getDomain() { + if (!(domain.startsWith("[") && domain.endsWith("]"))) { + return domain; + } + return domain.substring(1, domain.length() - 1); + } + + /** + * Returns the user part. + * + * @return the user part of this email address + * @deprecated use {@link #getLocalPart()}, whose name was changed to + * align with the RFC2822 3.4.1. addr-spec specification + */ + @Deprecated + public String getUser() { + return getLocalPart(); + } + + /** + * Returns the local-part per RFC2822 3.4.1. addr-spec specification. + * + * @return the local-part of this email address as defined by the + * RFC2822 3.4.1. addr-spec specification. + * The local-part portion is a domain dependent string. + * In addresses, it is simply interpreted on the particular + * host as a name of a particular mailbox + * (the part before the "@" character) + * @since Mailet API 2.4 + */ + public String getLocalPart() { + return localPart; + } + + public String asString() { + return localPart + "@" + domain; + } + + @Override + public String toString() { + return localPart + "@" + domain; + } + + public String asPrettyString() { + return '<' + asString() + '>'; + } + + /** + * Returns an InternetAddress representing the same address + * as this MailAddress. + * + * @return the address + */ + public InternetAddress toInternetAddress() { + try { + return new InternetAddress(toString()); + } catch (javax.mail.internet.AddressException ae) { + //impossible really + return null; + } + } + + /** + * Indicates whether some other object is "equal to" this one. + * <p/> + * Note that this implementation breaks the general contract of the + * <code>equals</code> method by allowing an instance to equal to a + * <code>String</code>. It is recommended that implementations avoid + * relying on this design which may be removed in a future release. + * + * @returns true if the given object is equal to this one, false otherwise + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } else if (obj instanceof String) { + String theString = (String) obj; + return toString().equalsIgnoreCase(theString); + } else if (obj instanceof MailAddress) { + MailAddress addr = (MailAddress) obj; + return getLocalPart().equalsIgnoreCase(addr.getLocalPart()) && getDomain().equalsIgnoreCase(addr.getDomain()); + } + return false; + } + + /** + * Returns a hash code value for this object. + * <p/> + * This method is implemented by returning the hash code of the canonical + * string representation of this address, so that all instances representing + * the same address will return an identical hash code. + * + * @return the hashcode. + */ + @Override + public int hashCode() { + return toString().toLowerCase(Locale.US).hashCode(); + } + + private int parseQuotedLocalPart(StringBuffer lpSB, String address, int pos) throws AddressException { + StringBuilder resultSB = new StringBuilder(); + resultSB.append('\"'); + pos++; + //<quoted-string> ::= """ <qtext> """ + //<qtext> ::= "\" <x> | "\" <x> <qtext> | <q> | <q> <qtext> + while (true) { + if (address.charAt(pos) == '\"') { + resultSB.append('\"'); + //end of quoted string... move forward + pos++; + break; + } + if (address.charAt(pos) == '\\') { + resultSB.append('\\'); + pos++; + //<x> ::= any one of the 128 ASCII characters (no exceptions) + char x = address.charAt(pos); + if (x < 0 || x > 127) { + throw new AddressException("Invalid \\ syntaxed character at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + resultSB.append(x); + pos++; + } else { + //<q> ::= any one of the 128 ASCII characters except <CR>, + //<LF>, quote ("), or backslash (\) + char q = address.charAt(pos); + if (q <= 0 || q == '\n' || q == '\r' || q == '\"' || q == '\\') { + throw new AddressException("Unquoted local-part (user account) must be one of the 128 ASCI " + + "characters exception <CR>, <LF>, quote (\"), or backslash (\\) at position " + + (pos + 1) + " in '" + address + "'"); + } + resultSB.append(q); + pos++; + } + } + lpSB.append(resultSB); + return pos; + } + + private int parseUnquotedLocalPart(StringBuffer lpSB, String address, int pos) throws AddressException { + StringBuilder resultSB = new StringBuilder(); + //<dot-string> ::= <string> | <string> "." <dot-string> + boolean lastCharDot = false; + while (true) { + //<string> ::= <char> | <char> <string> + //<char> ::= <c> | "\" <x> + if (address.charAt(pos) == '\\') { + resultSB.append('\\'); + pos++; + //<x> ::= any one of the 128 ASCII characters (no exceptions) + char x = address.charAt(pos); + if (x < 0 || x > 127) { + throw new AddressException("Invalid \\ syntaxed character at position " + (pos + 1) + + " in '" + address + "'", address, pos + 1); + } + resultSB.append(x); + pos++; + lastCharDot = false; + } else if (address.charAt(pos) == '.') { + if (pos == 0) { + throw new AddressException("Local part must not start with a '.'"); + } + resultSB.append('.'); + pos++; + lastCharDot = true; + } else if (address.charAt(pos) == '@') { + //End of local-part + break; + } else { + //<c> ::= any one of the 128 ASCII characters, but not any + // <special> or <SP> + //<special> ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "." + // | "," | ";" | ":" | "@" """ | the control + // characters (ASCII codes 0 through 31 inclusive and + // 127) + //<SP> ::= the space character (ASCII code 32) + char c = address.charAt(pos); + if (c <= 31 || c >= 127 || c == ' ') { + throw new AddressException("Invalid character in local-part (user account) at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + int i = 0; + while (i < SPECIAL.length) { + if (c == SPECIAL[i]) { + throw new AddressException("Invalid character in local-part (user account) at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + i++; + } + resultSB.append(c); + pos++; + lastCharDot = false; + } + } + if (lastCharDot) { + throw new AddressException("local-part (user account) ended with a \".\", which is invalid in address '" + + address + "'", address, pos); + } + lpSB.append(resultSB); + return pos; + } + + private int parseNumber(StringBuffer dSB, String address, int pos) throws AddressException { + //<number> ::= <d> | <d> <number> + + StringBuilder resultSB = new StringBuilder(); + // we were passed the string with pos pointing the the # char. + // take the first char (#), put it in the result buffer and increment pos + resultSB.append(address.charAt(pos)); + pos++; + //We keep the position from the class level pos field + while (true) { + if (pos >= address.length()) { + break; + } + //<d> ::= any one of the ten digits 0 through 9 + char d = address.charAt(pos); + if (d == '.') { + break; + } + if (d < '0' || d > '9') { + throw new AddressException("In domain, did not find a number in # address at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + resultSB.append(d); + pos++; + } + if (resultSB.length() < 2) { + throw new AddressException("In domain, did not find a number in # address at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + dSB.append(resultSB); + return pos; + } + + private int parseDomainLiteral(StringBuffer dSB, String address, int pos) throws AddressException { + StringBuilder resultSB = new StringBuilder(); + //we were passed the string with pos pointing the the [ char. + // take the first char ([), put it in the result buffer and increment pos + resultSB.append(address.charAt(pos)); + pos++; + + //<dotnum> ::= <snum> "." <snum> "." <snum> "." <snum> + for (int octet = 0; octet < 4; octet++) { + //<snum> ::= one, two, or three digits representing a decimal + // integer value in the range 0 through 255 + //<d> ::= any one of the ten digits 0 through 9 + StringBuilder snumSB = new StringBuilder(); + for (int digits = 0; digits < 3; digits++) { + char currentChar = address.charAt(pos); + if (currentChar == '.' || currentChar == ']') { + break; + } else if (currentChar < '0' || currentChar > '9') { + throw new AddressException("Invalid number at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + snumSB.append(currentChar); + pos++; + } + if (snumSB.toString().length() == 0) { + throw new AddressException("Number not found at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + try { + int snum = Integer.parseInt(snumSB.toString()); + if (snum > 255) { + throw new AddressException("Invalid number at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + } catch (NumberFormatException nfe) { + throw new AddressException("Invalid number at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + resultSB.append(snumSB.toString()); + if (address.charAt(pos) == ']') { + if (octet < 3) { + throw new AddressException("End of number reached too quickly at " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + break; + } + if (address.charAt(pos) == '.') { + resultSB.append('.'); + pos++; + } + } + if (address.charAt(pos) != ']') { + throw new AddressException("Did not find closing bracket \"]\" in domain at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + resultSB.append(']'); + pos++; + dSB.append(resultSB); + return pos; + } + + private int parseDomain(StringBuffer dSB, String address, int pos) throws AddressException { + StringBuilder resultSB = new StringBuilder(); + //<name> ::= <a> <ldh-str> <let-dig> + //<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str> + //<let-dig> ::= <a> | <d> + //<let-dig-hyp> ::= <a> | <d> | "-" + //<a> ::= any one of the 52 alphabetic characters A through Z + // in upper case and a through z in lower case + //<d> ::= any one of the ten digits 0 through 9 + + // basically, this is a series of letters, digits, and hyphens, + // but it can't start with a digit or hypthen + // and can't end with a hyphen + + // in practice though, we should relax this as domain names can start + // with digits as well as letters. So only check that doesn't start + // or end with hyphen. + while (true) { + if (pos >= address.length()) { + break; + } + char ch = address.charAt(pos); + if ((ch >= '0' && ch <= '9') || + (ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch == '-')) { + resultSB.append(ch); + pos++; + continue; + } + if (ch == '.') { + break; + } + throw new AddressException("Invalid character at " + pos + " in '" + address + "'", address, pos); + } + String result = resultSB.toString(); + if (result.startsWith("-") || result.endsWith("-")) { + throw new AddressException("Domain name cannot begin or end with a hyphen \"-\" at position " + + (pos + 1) + " in '" + address + "'", address, pos + 1); + } + dSB.append(result); + return pos; + } + + /** + * Return <code>true</code> if the {@link MailAddress} should represent a null sender (<>) + * + * @return nullsender + */ + public boolean isNullSender() { + return false; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/core/src/test/java/org/apache/james/core/MailAddressTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/james/core/MailAddressTest.java b/core/src/test/java/org/apache/james/core/MailAddressTest.java new file mode 100644 index 0000000..e4438ef --- /dev/null +++ b/core/src/test/java/org/apache/james/core/MailAddressTest.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.james.core; + +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; + +import org.apache.james.core.MailAddress; +import org.junit.Assert; +import org.junit.Test; + +public class MailAddressTest { + + private static final String + GOOD_LOCAL_PART = "\"quoted@local part\"", + GOOD_QUOTED_LOCAL_PART = "\"quoted@local part\"@james.apache.org", + GOOD_ADDRESS = "server-dev@james.apache.org", + GOOD_DOMAIN = "james.apache.org"; + + private static final String[] GOOD_ADDRESSES = { + GOOD_ADDRESS, + GOOD_QUOTED_LOCAL_PART, + "server-...@james-apache.org", + "server-dev@[127.0.0.1]", + "server-dev@#123", + "server-dev@#123.apache.org", + "server....@james.apache.org", + "\\.server-dev@james.apache.org", + "server-dev\\.@james.apache.org", + }; + + private static final String[] BAD_ADDRESSES = { + "", + "server-dev", + "server-dev@", + "[]", + "server-dev@[]", + "server-dev@#", + "quoted local-p...@james.apache.org", + "quoted@local-p...@james.apache.org", + "local-pa...@james.apache.org", + ".local-p...@james.apache.org", + "local-p...@.james.apache.org", + "local-p...@james.apache.org.", + "local-p...@james.apache..org", + "server-...@-james.apache.org", + "server-dev@james.apache.org-", + "server-dev@#james.apache.org", + "server-dev@#123james.apache.org", + "server-dev@#-123.james.apache.org", + "server-dev@james. apache.org", + "server-dev@james\\.apache.org", + "server-dev@[300.0.0.1]", + "server-dev@[127.0.1]", + "server-dev@[0127.0.0.1]", + "server-dev@[127.0.1.1a]", + "server-dev@[127\\.0.1.1]", + "server-dev@[127.0.1.1.1]", + "server-dev@[127.0.1.-1]" + }; + + /** + * Test method for {@link MailAddress#hashCode()}. + * + * @throws AddressException + */ + @Test + public void testHashCode() throws AddressException { + + MailAddress a = new MailAddress(GOOD_ADDRESS); + MailAddress b = new MailAddress(GOOD_ADDRESS); + Assert.assertTrue(a.hashCode() + " != " + b.hashCode(), a.hashCode() == b.hashCode()); + } + + /** + * Test method for {@link MailAddress#MailAddress(java.lang.String)}. + * + * @throws AddressException + */ + @Test + public void testMailAddressString() throws AddressException { + + MailAddress a = new MailAddress(GOOD_ADDRESS); + Assert.assertTrue(GOOD_ADDRESS.equals(a.toString())); + + for (String goodAddress : GOOD_ADDRESSES) { + try { + a = new MailAddress(goodAddress); + } catch (AddressException e) { + Assert.fail(e.getMessage()); + } + } + + for (String badAddress : BAD_ADDRESSES) { + try { + a = new MailAddress(badAddress); + Assert.fail(badAddress); + } catch (AddressException ignore) { + } + } + } + + /** + * Test method for {@link MailAddress#MailAddress(java.lang.String, java.lang.String)}. + */ + @Test + public void testMailAddressStringString() { + + try { + new MailAddress("local-part", "domain"); + } catch (AddressException e) { + Assert.assertTrue(e.getMessage(), false); + } + try { + MailAddress a = new MailAddress("local-part", "-domain"); + Assert.assertFalse(a.toString(), true); + } catch (AddressException e) { + Assert.assertTrue(true); + } + } + + /** + * Test method for {@link MailAddress#MailAddress(javax.mail.internet.InternetAddress)}. + */ + @Test + public void testMailAddressInternetAddress() { + + try { + new MailAddress(new InternetAddress(GOOD_QUOTED_LOCAL_PART)); + } catch (AddressException e) { + System.out.println("AddressException" + e.getMessage()); + Assert.assertTrue(e.getMessage(), false); + } + } + + /** + * Test method for {@link MailAddress#getDomain()}. + */ + @Test + public void testGetDomain() { + + try { + MailAddress a = new MailAddress(new InternetAddress(GOOD_ADDRESS)); + Assert.assertTrue(a.getDomain() + " != " + GOOD_DOMAIN, a.getDomain().equals(GOOD_DOMAIN)); + } catch (AddressException e) { + System.out.println("AddressException" + e.getMessage()); + Assert.assertTrue(e.getMessage(), false); + } + } + + /** + * Test method for {@link MailAddress#getLocalPart()}. + */ + @Test + public void testGetLocalPart() { + + try { + MailAddress a = new MailAddress(new InternetAddress(GOOD_QUOTED_LOCAL_PART)); + Assert.assertTrue(GOOD_LOCAL_PART + " != " + a.getLocalPart(), a.getLocalPart().equals(GOOD_LOCAL_PART)); + } catch (AddressException e) { + System.out.println("AddressException" + e.getMessage()); + Assert.assertTrue(e.getMessage(), false); + } + } + + /** + * Test method for {@link MailAddress#toString()}. + */ + @Test + public void testToString() { + + try { + MailAddress a = new MailAddress(new InternetAddress(GOOD_ADDRESS)); + Assert.assertTrue(a.toString() + " != " + GOOD_ADDRESS, a.toString().equals(GOOD_ADDRESS)); + } catch (AddressException e) { + System.out.println("AddressException" + e.getMessage()); + Assert.assertTrue(e.getMessage(), false); + } + } + + /** + * Test method for {@link MailAddress#toInternetAddress()}. + */ + @Test + public void testToInternetAddress() { + + try { + InternetAddress b = new InternetAddress(GOOD_ADDRESS); + MailAddress a = new MailAddress(b); + Assert.assertTrue(a.toInternetAddress().equals(b)); + Assert.assertTrue(a.toString() + " != " + GOOD_ADDRESS, a.toString().equals(GOOD_ADDRESS)); + } catch (AddressException e) { + System.out.println("AddressException" + e.getMessage()); + Assert.assertTrue(e.getMessage(), false); + } + } + + /** + * Test method for {@link MailAddress#equals(java.lang.Object)}. + * + * @throws AddressException + */ + @Test + public void testEqualsObject() throws AddressException { + + MailAddress a = new MailAddress(GOOD_ADDRESS); + MailAddress b = new MailAddress(GOOD_ADDRESS); + + Assert.assertTrue(a.toString() + " != " + b.toString(), a.equals(b)); + Assert.assertFalse(a.toString() + " != " + null, a.equals(null)); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java ---------------------------------------------------------------------- diff --git a/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java b/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java index b96e5a2..5acc119 100644 --- a/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java +++ b/mailet/ai/src/main/java/org/apache/james/ai/classic/BayesianAnalysis.java @@ -34,7 +34,7 @@ import javax.sql.DataSource; import org.apache.mailet.Experimental; import org.apache.mailet.Mail; -import org.apache.mailet.MailAddress; +import org.apache.james.core.MailAddress; import org.apache.mailet.base.GenericMailet; import org.apache.mailet.base.RFC2822Headers; import org.slf4j.Logger; http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/pom.xml ---------------------------------------------------------------------- diff --git a/mailet/api/pom.xml b/mailet/api/pom.xml index 53b4764..e12bd4c 100644 --- a/mailet/api/pom.xml +++ b/mailet/api/pom.xml @@ -37,6 +37,10 @@ <dependencies> <dependency> + <groupId>${groupId}</groupId> + <artifactId>james-core</artifactId> + </dependency> + <dependency> <groupId>com.github.steveash.guavate</groupId> <artifactId>guavate</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/Mail.java ---------------------------------------------------------------------- diff --git a/mailet/api/src/main/java/org/apache/mailet/Mail.java b/mailet/api/src/main/java/org/apache/mailet/Mail.java index 158359a..3339370 100644 --- a/mailet/api/src/main/java/org/apache/mailet/Mail.java +++ b/mailet/api/src/main/java/org/apache/mailet/Mail.java @@ -22,6 +22,7 @@ package org.apache.mailet; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; +import org.apache.james.core.MailAddress; import org.apache.mailet.PerRecipientHeaders.Header; import java.io.Serializable; http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/MailAddress.java ---------------------------------------------------------------------- diff --git a/mailet/api/src/main/java/org/apache/mailet/MailAddress.java b/mailet/api/src/main/java/org/apache/mailet/MailAddress.java index fbca0a5..0043ac9 100644 --- a/mailet/api/src/main/java/org/apache/mailet/MailAddress.java +++ b/mailet/api/src/main/java/org/apache/mailet/MailAddress.java @@ -17,564 +17,24 @@ * under the License. * ****************************************************************/ - package org.apache.mailet; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; -import java.util.Locale; - -/** - * A representation of an email address. - * <p/> - * <p>This class encapsulates functionality to access different - * parts of an email address without dealing with its parsing.</p> - * <p/> - * <p>A MailAddress is an address specified in the MAIL FROM and - * RCPT TO commands in SMTP sessions. These are either passed by - * an external server to the mailet-compliant SMTP server, or they - * are created programmatically by the mailet-compliant server to - * send to another (external) SMTP server. Mailets and matchers - * use the MailAddress for the purpose of evaluating the sender - * and recipient(s) of a message.</p> - * <p/> - * <p>MailAddress parses an email address as defined in RFC 821 - * (SMTP) p. 30 and 31 where addresses are defined in BNF convention. - * As the mailet API does not support the aged "SMTP-relayed mail" - * addressing protocol, this leaves all addresses to be a {@code <mailbox>}, - * as per the spec. - * <p/> - * <p>This class is a good way to validate email addresses as there are - * some valid addresses which would fail with a simpler approach - * to parsing address. It also removes the parsing burden from - * mailets and matchers that might not realize the flexibility of an - * SMTP address. For instance, "serge@home"@lokitech.com is a valid - * SMTP address (the quoted text serge@home is the local-part and - * lokitech.com is the domain). This means all current parsing to date - * is incorrect as we just find the first '@' and use that to separate - * local-part from domain.</p> - * <p/> - * <p>This parses an address as per the BNF specification for <mailbox> - * from RFC 821 on page 30 and 31, section 4.1.2. COMMAND SYNTAX. - * http://www.freesoft.org/CIE/RFC/821/15.htm</p> - * - * @version 1.0 - */ -public class MailAddress implements java.io.Serializable { - /** - * We hardcode the serialVersionUID - * This version (2779163542539434916L) retains compatibility back to - * Mailet version 1.2 (James 1.2) so that MailAddress will be - * deserializable and mail doesn't get lost after an upgrade. - */ - public static final long serialVersionUID = 2779163542539434916L; - - private final static char[] SPECIAL = - {'<', '>', '(', ')', '[', ']', '\\', '.', ',', ';', ':', '@', '\"'}; - private String localPart = null; - private String domain = null; +@Deprecated +public class MailAddress extends org.apache.james.core.MailAddress { - /** - * Strips source routing. According to RFC-2821 it is a valid approach - * to handle mails containing RFC-821 source-route information. - * - * @param address the address to strip - * @param pos current position - * @return new pos - */ - private int stripSourceRoute(String address, int pos) { - if (pos < address.length()) { - if (address.charAt(pos) == '@') { - int i = address.indexOf(':'); - if (i != -1) { - pos = i + 1; - } - } - } - return pos; - } - - /** - * Constructs a MailAddress by parsing the provided address. - * - * @param address the email address, compliant to the RFC2822 3.4.1. addr-spec specification - * @throws AddressException if the parse failed - */ public MailAddress(String address) throws AddressException { - address = address.trim(); - int pos = 0; - - // Test if mail address has source routing information (RFC-821) and get rid of it!! - //must be called first!! (or at least prior to updating pos) - stripSourceRoute(address, pos); - - StringBuffer localPartSB = new StringBuffer(); - StringBuffer domainSB = new StringBuffer(); - //Begin parsing - //<mailbox> ::= <local-part> "@" <domain> - - try { - //parse local-part - //<local-part> ::= <dot-string> | <quoted-string> - if (address.charAt(pos) == '\"') { - pos = parseQuotedLocalPartOrThrowException(localPartSB, address, pos); - } else { - pos = parseUnquotedLocalPartOrThrowException(localPartSB, address, pos); - } - - //find @ - if (pos >= address.length() || address.charAt(pos) != '@') { - throw new AddressException("Did not find @ between local-part and domain at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - pos++; - - //parse domain - //<domain> ::= <element> | <element> "." <domain> - //<element> ::= <name> | "#" <number> | "[" <dotnum> "]" - while (true) { - if (address.charAt(pos) == '#') { - pos = parseNumber(domainSB, address, pos); - } else if (address.charAt(pos) == '[') { - pos = parseDomainLiteral(domainSB, address, pos); - } else { - pos = parseDomain(domainSB, address, pos); - } - if (pos >= address.length()) { - break; - } - if (address.charAt(pos) == '.') { - char lastChar = address.charAt(pos - 1); - if (lastChar == '@' || lastChar == '.') { - throw new AddressException("Subdomain expected before '.' or duplicate '.' in " + address); - } - domainSB.append('.'); - pos++; - continue; - } - break; - } - - if (domainSB.toString().length() == 0) { - throw new AddressException("No domain found at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - } catch (IndexOutOfBoundsException ioobe) { - throw new AddressException("Out of data at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - - localPart = localPartSB.toString(); - domain = domainSB.toString(); + super(address); } - private int parseUnquotedLocalPartOrThrowException(StringBuffer localPartSB, String address, int pos) - throws AddressException { - pos = parseUnquotedLocalPart(localPartSB, address, pos); - if (localPartSB.toString().length() == 0) { - throw new AddressException("No local-part (user account) found at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - return pos; - } - - private int parseQuotedLocalPartOrThrowException(StringBuffer localPartSB, String address, int pos) - throws AddressException { - pos = parseQuotedLocalPart(localPartSB, address, pos); - if (localPartSB.toString().length() == 2) { - throw new AddressException("No quoted local-part (user account) found at position " + - (pos + 2) + " in '" + address + "'", address, pos + 2); - } - return pos; - } - - /** - * Constructs a MailAddress with the provided local part and domain. - * - * @param localPart the local-part portion. This is a domain dependent string. - * In addresses, it is simply interpreted on the particular host as a - * name of a particular mailbox. per RFC2822 3.4.1. addr-spec specification - * @param domain the domain portion. This identifies the point to which the mail - * is delivered per RFC2822 3.4.1. addr-spec specification - * @throws AddressException if the parse failed - */ public MailAddress(String localPart, String domain) throws AddressException { - this(new InternetAddress(localPart + "@" + domain)); + super(localPart, domain); } - /** - * Constructs a MailAddress from an InternetAddress, using only the - * email address portion (an "addr-spec", not "name-addr", as - * defined in the RFC2822 3.4. Address Specification) - * - * @param address the address - * @throws AddressException if the parse failed - */ public MailAddress(InternetAddress address) throws AddressException { - this(address.getAddress()); - } - - /** - * Returns the host part. - * - * @return the host part of this email address. If the host is of the - * dotNum form (e.g. [yyy.yyy.yyy.yyy]), then strip the braces first. - * @deprecated use {@link #getDomain()}, whose name was changed to - * align with RFC2822 3.4.1. addr-spec specification - */ - @Deprecated - public String getHost() { - return getDomain(); - } - - /** - * Returns the domain part per RFC2822 3.4.1. addr-spec specification. - * - * @return the domain part of this email address. If the domain is of - * the domain-literal form (e.g. [yyy.yyy.yyy.yyy]), the braces will - * have been stripped returning the raw IP address. - * @since Mailet API 2.4 - */ - public String getDomain() { - if (!(domain.startsWith("[") && domain.endsWith("]"))) { - return domain; - } - return domain.substring(1, domain.length() - 1); - } - - /** - * Returns the user part. - * - * @return the user part of this email address - * @deprecated use {@link #getLocalPart()}, whose name was changed to - * align with the RFC2822 3.4.1. addr-spec specification - */ - @Deprecated - public String getUser() { - return getLocalPart(); - } - - /** - * Returns the local-part per RFC2822 3.4.1. addr-spec specification. - * - * @return the local-part of this email address as defined by the - * RFC2822 3.4.1. addr-spec specification. - * The local-part portion is a domain dependent string. - * In addresses, it is simply interpreted on the particular - * host as a name of a particular mailbox - * (the part before the "@" character) - * @since Mailet API 2.4 - */ - public String getLocalPart() { - return localPart; + super(address); } - public String asString() { - return localPart + "@" + domain; - } - - @Override - public String toString() { - return localPart + "@" + domain; - } - - public String asPrettyString() { - return '<' + asString() + '>'; - } - - /** - * Returns an InternetAddress representing the same address - * as this MailAddress. - * - * @return the address - */ - public InternetAddress toInternetAddress() { - try { - return new InternetAddress(toString()); - } catch (javax.mail.internet.AddressException ae) { - //impossible really - return null; - } - } - - /** - * Indicates whether some other object is "equal to" this one. - * <p/> - * Note that this implementation breaks the general contract of the - * <code>equals</code> method by allowing an instance to equal to a - * <code>String</code>. It is recommended that implementations avoid - * relying on this design which may be removed in a future release. - * - * @returns true if the given object is equal to this one, false otherwise - */ - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } else if (obj instanceof String) { - String theString = (String) obj; - return toString().equalsIgnoreCase(theString); - } else if (obj instanceof MailAddress) { - MailAddress addr = (MailAddress) obj; - return getLocalPart().equalsIgnoreCase(addr.getLocalPart()) && getDomain().equalsIgnoreCase(addr.getDomain()); - } - return false; - } - - /** - * Returns a hash code value for this object. - * <p/> - * This method is implemented by returning the hash code of the canonical - * string representation of this address, so that all instances representing - * the same address will return an identical hash code. - * - * @return the hashcode. - */ - @Override - public int hashCode() { - return toString().toLowerCase(Locale.US).hashCode(); - } - - private int parseQuotedLocalPart(StringBuffer lpSB, String address, int pos) throws AddressException { - StringBuilder resultSB = new StringBuilder(); - resultSB.append('\"'); - pos++; - //<quoted-string> ::= """ <qtext> """ - //<qtext> ::= "\" <x> | "\" <x> <qtext> | <q> | <q> <qtext> - while (true) { - if (address.charAt(pos) == '\"') { - resultSB.append('\"'); - //end of quoted string... move forward - pos++; - break; - } - if (address.charAt(pos) == '\\') { - resultSB.append('\\'); - pos++; - //<x> ::= any one of the 128 ASCII characters (no exceptions) - char x = address.charAt(pos); - if (x < 0 || x > 127) { - throw new AddressException("Invalid \\ syntaxed character at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - resultSB.append(x); - pos++; - } else { - //<q> ::= any one of the 128 ASCII characters except <CR>, - //<LF>, quote ("), or backslash (\) - char q = address.charAt(pos); - if (q <= 0 || q == '\n' || q == '\r' || q == '\"' || q == '\\') { - throw new AddressException("Unquoted local-part (user account) must be one of the 128 ASCI " + - "characters exception <CR>, <LF>, quote (\"), or backslash (\\) at position " + - (pos + 1) + " in '" + address + "'"); - } - resultSB.append(q); - pos++; - } - } - lpSB.append(resultSB); - return pos; - } - - private int parseUnquotedLocalPart(StringBuffer lpSB, String address, int pos) throws AddressException { - StringBuilder resultSB = new StringBuilder(); - //<dot-string> ::= <string> | <string> "." <dot-string> - boolean lastCharDot = false; - while (true) { - //<string> ::= <char> | <char> <string> - //<char> ::= <c> | "\" <x> - if (address.charAt(pos) == '\\') { - resultSB.append('\\'); - pos++; - //<x> ::= any one of the 128 ASCII characters (no exceptions) - char x = address.charAt(pos); - if (x < 0 || x > 127) { - throw new AddressException("Invalid \\ syntaxed character at position " + (pos + 1) + - " in '" + address + "'", address, pos + 1); - } - resultSB.append(x); - pos++; - lastCharDot = false; - } else if (address.charAt(pos) == '.') { - if (pos == 0) { - throw new AddressException("Local part must not start with a '.'"); - } - resultSB.append('.'); - pos++; - lastCharDot = true; - } else if (address.charAt(pos) == '@') { - //End of local-part - break; - } else { - //<c> ::= any one of the 128 ASCII characters, but not any - // <special> or <SP> - //<special> ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "." - // | "," | ";" | ":" | "@" """ | the control - // characters (ASCII codes 0 through 31 inclusive and - // 127) - //<SP> ::= the space character (ASCII code 32) - char c = address.charAt(pos); - if (c <= 31 || c >= 127 || c == ' ') { - throw new AddressException("Invalid character in local-part (user account) at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - int i = 0; - while (i < SPECIAL.length) { - if (c == SPECIAL[i]) { - throw new AddressException("Invalid character in local-part (user account) at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - i++; - } - resultSB.append(c); - pos++; - lastCharDot = false; - } - } - if (lastCharDot) { - throw new AddressException("local-part (user account) ended with a \".\", which is invalid in address '" + - address + "'", address, pos); - } - lpSB.append(resultSB); - return pos; - } - - private int parseNumber(StringBuffer dSB, String address, int pos) throws AddressException { - //<number> ::= <d> | <d> <number> - - StringBuilder resultSB = new StringBuilder(); - // we were passed the string with pos pointing the the # char. - // take the first char (#), put it in the result buffer and increment pos - resultSB.append(address.charAt(pos)); - pos++; - //We keep the position from the class level pos field - while (true) { - if (pos >= address.length()) { - break; - } - //<d> ::= any one of the ten digits 0 through 9 - char d = address.charAt(pos); - if (d == '.') { - break; - } - if (d < '0' || d > '9') { - throw new AddressException("In domain, did not find a number in # address at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - resultSB.append(d); - pos++; - } - if (resultSB.length() < 2) { - throw new AddressException("In domain, did not find a number in # address at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - dSB.append(resultSB); - return pos; - } - - private int parseDomainLiteral(StringBuffer dSB, String address, int pos) throws AddressException { - StringBuilder resultSB = new StringBuilder(); - //we were passed the string with pos pointing the the [ char. - // take the first char ([), put it in the result buffer and increment pos - resultSB.append(address.charAt(pos)); - pos++; - - //<dotnum> ::= <snum> "." <snum> "." <snum> "." <snum> - for (int octet = 0; octet < 4; octet++) { - //<snum> ::= one, two, or three digits representing a decimal - // integer value in the range 0 through 255 - //<d> ::= any one of the ten digits 0 through 9 - StringBuilder snumSB = new StringBuilder(); - for (int digits = 0; digits < 3; digits++) { - char currentChar = address.charAt(pos); - if (currentChar == '.' || currentChar == ']') { - break; - } else if (currentChar < '0' || currentChar > '9') { - throw new AddressException("Invalid number at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - snumSB.append(currentChar); - pos++; - } - if (snumSB.toString().length() == 0) { - throw new AddressException("Number not found at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - try { - int snum = Integer.parseInt(snumSB.toString()); - if (snum > 255) { - throw new AddressException("Invalid number at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - } catch (NumberFormatException nfe) { - throw new AddressException("Invalid number at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - resultSB.append(snumSB.toString()); - if (address.charAt(pos) == ']') { - if (octet < 3) { - throw new AddressException("End of number reached too quickly at " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - break; - } - if (address.charAt(pos) == '.') { - resultSB.append('.'); - pos++; - } - } - if (address.charAt(pos) != ']') { - throw new AddressException("Did not find closing bracket \"]\" in domain at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - resultSB.append(']'); - pos++; - dSB.append(resultSB); - return pos; - } - - private int parseDomain(StringBuffer dSB, String address, int pos) throws AddressException { - StringBuilder resultSB = new StringBuilder(); - //<name> ::= <a> <ldh-str> <let-dig> - //<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str> - //<let-dig> ::= <a> | <d> - //<let-dig-hyp> ::= <a> | <d> | "-" - //<a> ::= any one of the 52 alphabetic characters A through Z - // in upper case and a through z in lower case - //<d> ::= any one of the ten digits 0 through 9 - - // basically, this is a series of letters, digits, and hyphens, - // but it can't start with a digit or hypthen - // and can't end with a hyphen - - // in practice though, we should relax this as domain names can start - // with digits as well as letters. So only check that doesn't start - // or end with hyphen. - while (true) { - if (pos >= address.length()) { - break; - } - char ch = address.charAt(pos); - if ((ch >= '0' && ch <= '9') || - (ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch == '-')) { - resultSB.append(ch); - pos++; - continue; - } - if (ch == '.') { - break; - } - throw new AddressException("Invalid character at " + pos + " in '" + address + "'", address, pos); - } - String result = resultSB.toString(); - if (result.startsWith("-") || result.endsWith("-")) { - throw new AddressException("Domain name cannot begin or end with a hyphen \"-\" at position " + - (pos + 1) + " in '" + address + "'", address, pos + 1); - } - dSB.append(result); - return pos; - } } http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/MailetContext.java ---------------------------------------------------------------------- diff --git a/mailet/api/src/main/java/org/apache/mailet/MailetContext.java b/mailet/api/src/main/java/org/apache/mailet/MailetContext.java index 2b2dd96..202caf7 100644 --- a/mailet/api/src/main/java/org/apache/mailet/MailetContext.java +++ b/mailet/api/src/main/java/org/apache/mailet/MailetContext.java @@ -27,6 +27,7 @@ import java.util.List; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; +import org.apache.james.core.MailAddress; import org.slf4j.Logger; /** http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/Matcher.java ---------------------------------------------------------------------- diff --git a/mailet/api/src/main/java/org/apache/mailet/Matcher.java b/mailet/api/src/main/java/org/apache/mailet/Matcher.java index a444a84..3d71072 100644 --- a/mailet/api/src/main/java/org/apache/mailet/Matcher.java +++ b/mailet/api/src/main/java/org/apache/mailet/Matcher.java @@ -23,6 +23,8 @@ package org.apache.mailet; import java.util.Collection; import javax.mail.MessagingException; +import org.apache.james.core.MailAddress; + /** * This interface defines the behaviour of the message "routing" inside * the mailet container. At its heart is the {@link #match(Mail)} method, http://git-wip-us.apache.org/repos/asf/james-project/blob/936746b9/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java ---------------------------------------------------------------------- diff --git a/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java b/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java index af9b233..0b7bcdb 100644 --- a/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java +++ b/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java @@ -21,6 +21,8 @@ package org.apache.mailet; import java.util.Collection; +import org.apache.james.core.MailAddress; + import com.github.steveash.guavate.Guavate; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org