EmailAddress.java

1
package fr.sii.ogham.email.message;
2
3
import java.util.regex.Matcher;
4
import java.util.regex.Pattern;
5
6
import fr.sii.ogham.core.util.EqualsBuilder;
7
import fr.sii.ogham.core.util.HashCodeBuilder;
8
9
/**
10
 * Represents an email address. javax.mail.internet.InternetAddress also
11
 * provides the same feature but we don't want to be sticked to a particular
12
 * implementation.
13
 * 
14
 * @author Aurélien Baudet
15
 *
16
 */
17
public class EmailAddress {
18
	private static final String QUOTED = "([\"](?<personal1>[^\"]+)[\"])";
19
	private static final String UNQUOTED = "(?<personal2>.+)";
20
	private static final String ADDRESS_WITH_TAG = "<(?<address>[^>]+)>";
21
	private static final Pattern SIMPLE_ADDRESS_WITH_PERSONAL = Pattern.compile("\\s*("+QUOTED+"|"+UNQUOTED+")\\s* "+ADDRESS_WITH_TAG);
22
23
	/**
24
	 * The email address part (is of the form "user@domain.host")
25
	 */
26
	private String address;
27
28
	/**
29
	 * The user name part (can be anything)
30
	 */
31
	private String personal;
32
33
	/**
34
	 * Initialize the address with only the email address part (no personal). It
35
	 * is of the form "user@domain.host" or and "Personal Name
36
	 * &lt;user@host.domain&gt;" formats.
37
	 * 
38
	 * When using an address of the form "Personal Name
39
	 * &lt;user@host.domain&gt;", the address is parsed to split into two
40
	 * fields:
41
	 * <ul>
42
	 * <li>email address ("user@domain.host"), accessible through
43
	 * {@link #getAddress()}</li>
44
	 * <li>personal name if any ("Personal Name"), accessible through
45
	 * {@link #getPersonal()}</li>
46
	 * </ul>
47
	 * 
48
	 * <strong>IMPORTANT: The parsing of address and personal only supports
49
	 * simple cases. The cases defined in RFC822 and RFC2822 with comments,
50
	 * mailbox and group are not supported.</strong> If you need this feature,
51
	 * you need to use an external parser in order to extract information. If
52
	 * an address containing mailbox or group is provided, then no personal name
53
	 * is extracted but address is the full string.
54
	 * 
55
	 * @param rawAddress
56
	 *            the email address part
57
	 */
58
	public EmailAddress(String rawAddress) {
59
		super();
60
		EmailAddress parsed = parse(rawAddress);
61
		address = parsed.getAddress();
62
		personal = parsed.getPersonal();
63
	}
64
65
	/**
66
	 * Initialize the address with the email address and the personal parts.
67
	 * No parsing is applied.
68
	 * 
69
	 * @param address
70
	 *            the email address part, it is of the form "user@domain.host"
71
	 * @param personal
72
	 *            the personal part
73
	 */
74
	public EmailAddress(String address, String personal) {
75
		super();
76
		this.address = address;
77
		this.personal = personal;
78
	}
79
80
	public String getAddress() {
81 5 1. getAddress : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → NO_COVERAGE
2. getAddress : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → TIMED_OUT
3. getAddress : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → KILLED
4. getAddress : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → KILLED
5. getAddress : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → KILLED
		return address;
82
	}
83
84
	public String getPersonal() {
85 5 1. getPersonal : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → NO_COVERAGE
2. getPersonal : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → SURVIVED
3. getPersonal : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → TIMED_OUT
4. getPersonal : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → KILLED
5. getPersonal : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → KILLED
		return personal;
86
	}
87
88
	@Override
89
	public String toString() {
90
		StringBuilder builder = new StringBuilder();
91 5 1. toString : negated conditional → SURVIVED
2. toString : negated conditional → NO_COVERAGE
3. toString : negated conditional → NO_COVERAGE
4. toString : negated conditional → SURVIVED
5. toString : negated conditional → TIMED_OUT
		if (personal != null && !personal.isEmpty()) {
92
			builder.append(personal).append(" ");
93
		}
94
		builder.append("<").append(address).append(">");
95 3 1. toString : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::toString → NO_COVERAGE
2. toString : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::toString → SURVIVED
3. toString : replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::toString → TIMED_OUT
		return builder.toString();
96
	}
97
98
	@Override
99
	public int hashCode() {
100 2 1. hashCode : replaced int return with 0 for fr/sii/ogham/email/message/EmailAddress::hashCode → NO_COVERAGE
2. hashCode : replaced int return with 0 for fr/sii/ogham/email/message/EmailAddress::hashCode → KILLED
		return new HashCodeBuilder().append(address, personal).hashCode();
101
	}
102
103
	@Override
104
	public boolean equals(Object obj) {
105 6 1. equals : replaced boolean return with false for fr/sii/ogham/email/message/EmailAddress::equals → NO_COVERAGE
2. equals : replaced boolean return with true for fr/sii/ogham/email/message/EmailAddress::equals → SURVIVED
3. equals : replaced boolean return with true for fr/sii/ogham/email/message/EmailAddress::equals → NO_COVERAGE
4. equals : replaced boolean return with false for fr/sii/ogham/email/message/EmailAddress::equals → KILLED
5. equals : replaced boolean return with false for fr/sii/ogham/email/message/EmailAddress::equals → KILLED
6. equals : replaced boolean return with true for fr/sii/ogham/email/message/EmailAddress::equals → KILLED
		return new EqualsBuilder(this, obj).appendFields("address", "personal").isEqual();
106
	}
107
108
	public static EmailAddress parse(String rawAddress) {
109 5 1. parse : negated conditional → NO_COVERAGE
2. parse : negated conditional → TIMED_OUT
3. parse : negated conditional → KILLED
4. parse : negated conditional → KILLED
5. parse : negated conditional → KILLED
		if(rawAddress == null) {
110
			throw new IllegalArgumentException("Address can't be null");
111
		}
112
		Matcher matcher = SIMPLE_ADDRESS_WITH_PERSONAL.matcher(rawAddress);
113 5 1. parse : negated conditional → NO_COVERAGE
2. parse : negated conditional → TIMED_OUT
3. parse : negated conditional → KILLED
4. parse : negated conditional → KILLED
5. parse : negated conditional → KILLED
		if(matcher.matches()) {
114
			String address = matcher.group("address");
115 3 1. parse : negated conditional → NO_COVERAGE
2. parse : negated conditional → KILLED
3. parse : negated conditional → KILLED
			String personal = matcher.group("personal1") != null ? matcher.group("personal1") : matcher.group("personal2");
116 3 1. parse : replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → NO_COVERAGE
2. parse : replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED
3. parse : replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED
			return new EmailAddress(address, personal);
117
		}
118 5 1. parse : replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → NO_COVERAGE
2. parse : replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → TIMED_OUT
3. parse : replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED
4. parse : replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED
5. parse : replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED
		return new EmailAddress(rawAddress, null);
119
	}
120
}

Mutations

81

1.1
Location : getAddress
Killed by : none
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → NO_COVERAGE

2.2
Location : getAddress
Killed by : none
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → TIMED_OUT

3.3
Location : getAddress
Killed by : oghamjavamail.it.JavaMailStructureTest.plainTextBody(oghamjavamail.it.JavaMailStructureTest)
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → KILLED

4.4
Location : getAddress
Killed by : oghamall.it.configuration.EmptyBuilderTest.emailSenderManuallyRegisteredButUnconfiguredTemplateParsersCantHandleMultiTemplateContent(oghamall.it.configuration.EmptyBuilderTest)
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → KILLED

5.5
Location : getAddress
Killed by : oghamcore.ut.email.ParseEmailAddressSpec
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getAddress → KILLED

85

1.1
Location : getPersonal
Killed by : oghamcore.ut.email.ParseEmailAddressSpec
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → KILLED

2.2
Location : getPersonal
Killed by : none
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → TIMED_OUT

3.3
Location : getPersonal
Killed by : oghamall.it.email.EmailSMTPAuthenticationTest.authenticated(oghamall.it.email.EmailSMTPAuthenticationTest)
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → KILLED

4.4
Location : getPersonal
Killed by : none
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → NO_COVERAGE

5.5
Location : getPersonal
Killed by : none
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::getPersonal → SURVIVED

91

1.1
Location : toString
Killed by : none
negated conditional → SURVIVED

2.2
Location : toString
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : toString
Killed by : none
negated conditional → TIMED_OUT

4.4
Location : toString
Killed by : none
negated conditional → NO_COVERAGE

5.5
Location : toString
Killed by : none
negated conditional → SURVIVED

95

1.1
Location : toString
Killed by : none
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::toString → NO_COVERAGE

2.2
Location : toString
Killed by : none
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::toString → TIMED_OUT

3.3
Location : toString
Killed by : none
replaced return value with "" for fr/sii/ogham/email/message/EmailAddress::toString → SURVIVED

100

1.1
Location : hashCode
Killed by : oghamcore.ut.email.EqualsTest.recipient(oghamcore.ut.email.EqualsTest)
replaced int return with 0 for fr/sii/ogham/email/message/EmailAddress::hashCode → KILLED

2.2
Location : hashCode
Killed by : none
replaced int return with 0 for fr/sii/ogham/email/message/EmailAddress::hashCode → NO_COVERAGE

105

1.1
Location : equals
Killed by : none
replaced boolean return with false for fr/sii/ogham/email/message/EmailAddress::equals → NO_COVERAGE

2.2
Location : equals
Killed by : oghamall.it.email.EmailCustomImplTest.simple(oghamall.it.email.EmailCustomImplTest)
replaced boolean return with false for fr/sii/ogham/email/message/EmailAddress::equals → KILLED

3.3
Location : equals
Killed by : oghamcore.ut.email.EqualsTest.recipient(oghamcore.ut.email.EqualsTest)
replaced boolean return with false for fr/sii/ogham/email/message/EmailAddress::equals → KILLED

4.4
Location : equals
Killed by : none
replaced boolean return with true for fr/sii/ogham/email/message/EmailAddress::equals → SURVIVED

5.5
Location : equals
Killed by : oghamcore.ut.email.EqualsTest.recipient(oghamcore.ut.email.EqualsTest)
replaced boolean return with true for fr/sii/ogham/email/message/EmailAddress::equals → KILLED

6.6
Location : equals
Killed by : none
replaced boolean return with true for fr/sii/ogham/email/message/EmailAddress::equals → NO_COVERAGE

109

1.1
Location : parse
Killed by : oghamcore.ut.email.ParseEmailAddressSpec
negated conditional → KILLED

2.2
Location : parse
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : parse
Killed by : none
negated conditional → TIMED_OUT

4.4
Location : parse
Killed by : oghamjavamail.it.JavaMailStructureTest.plainTextBody(oghamjavamail.it.JavaMailStructureTest)
negated conditional → KILLED

5.5
Location : parse
Killed by : oghamall.it.configuration.EmptyBuilderTest.unconfiguredServiceCantSendEmail(oghamall.it.configuration.EmptyBuilderTest)
negated conditional → KILLED

113

1.1
Location : parse
Killed by : oghamjavamail.it.JavaMailStructureTest.plainTextBody(oghamjavamail.it.JavaMailStructureTest)
negated conditional → KILLED

2.2
Location : parse
Killed by : oghamall.it.configuration.EmptyBuilderTest.unconfiguredServiceCantSendEmail(oghamall.it.configuration.EmptyBuilderTest)
negated conditional → KILLED

3.3
Location : parse
Killed by : none
negated conditional → TIMED_OUT

4.4
Location : parse
Killed by : none
negated conditional → NO_COVERAGE

5.5
Location : parse
Killed by : oghamcore.ut.email.ParseEmailAddressSpec
negated conditional → KILLED

115

1.1
Location : parse
Killed by : oghamcore.ut.email.ParseEmailAddressSpec
negated conditional → KILLED

2.2
Location : parse
Killed by : oghamall.it.email.EmailSMTPAuthenticationTest.authenticated(oghamall.it.email.EmailSMTPAuthenticationTest)
negated conditional → KILLED

3.3
Location : parse
Killed by : none
negated conditional → NO_COVERAGE

116

1.1
Location : parse
Killed by : oghamcore.ut.email.ParseEmailAddressSpec
replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED

2.2
Location : parse
Killed by : oghamall.it.email.EmailSMTPAuthenticationTest.authenticated(oghamall.it.email.EmailSMTPAuthenticationTest)
replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED

3.3
Location : parse
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → NO_COVERAGE

118

1.1
Location : parse
Killed by : oghamall.it.configuration.EmptyBuilderTest.unconfiguredServiceCantSendEmail(oghamall.it.configuration.EmptyBuilderTest)
replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED

2.2
Location : parse
Killed by : oghamjavamail.it.JavaMailStructureTest.plainTextBody(oghamjavamail.it.JavaMailStructureTest)
replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED

3.3
Location : parse
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → NO_COVERAGE

4.4
Location : parse
Killed by : none
replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → TIMED_OUT

5.5
Location : parse
Killed by : oghamcore.ut.email.ParseEmailAddressSpec
replaced return value with null for fr/sii/ogham/email/message/EmailAddress::parse → KILLED

Active mutators

Tests examined


Report generated by PIT OGHAM