summaryrefslogtreecommitdiffstats
path: root/java/com/google/gerrit/mail/EmailHeader.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/google/gerrit/mail/EmailHeader.java')
-rw-r--r--java/com/google/gerrit/mail/EmailHeader.java233
1 files changed, 233 insertions, 0 deletions
diff --git a/java/com/google/gerrit/mail/EmailHeader.java b/java/com/google/gerrit/mail/EmailHeader.java
new file mode 100644
index 0000000000..69d5fcdaab
--- /dev/null
+++ b/java/com/google/gerrit/mail/EmailHeader.java
@@ -0,0 +1,233 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// 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 com.google.gerrit.mail;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.base.MoreObjects;
+import java.io.IOException;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+
+public abstract class EmailHeader {
+ public abstract boolean isEmpty();
+
+ public abstract void write(Writer w) throws IOException;
+
+ public static class String extends EmailHeader {
+ private final java.lang.String value;
+
+ public String(java.lang.String v) {
+ value = v;
+ }
+
+ public java.lang.String getString() {
+ return value;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return value == null || value.length() == 0;
+ }
+
+ @Override
+ public void write(Writer w) throws IOException {
+ if (needsQuotedPrintable(value)) {
+ w.write(quotedPrintable(value));
+ } else {
+ w.write(value);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof String) && Objects.equals(value, ((String) o).value);
+ }
+
+ @Override
+ public java.lang.String toString() {
+ return MoreObjects.toStringHelper(this).addValue(value).toString();
+ }
+ }
+
+ public static boolean needsQuotedPrintable(java.lang.String value) {
+ for (int i = 0; i < value.length(); i++) {
+ if (value.charAt(i) < ' ' || '~' < value.charAt(i)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static boolean needsQuotedPrintableWithinPhrase(int cp) {
+ switch (cp) {
+ case '!':
+ case '*':
+ case '+':
+ case '-':
+ case '/':
+ case '=':
+ case '_':
+ return false;
+ default:
+ if (('a' <= cp && cp <= 'z') || ('A' <= cp && cp <= 'Z') || ('0' <= cp && cp <= '9')) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public static java.lang.String quotedPrintable(java.lang.String value) {
+ final StringBuilder r = new StringBuilder();
+
+ r.append("=?UTF-8?Q?");
+ for (int i = 0; i < value.length(); i++) {
+ final int cp = value.codePointAt(i);
+ if (cp == ' ') {
+ r.append('_');
+
+ } else if (needsQuotedPrintableWithinPhrase(cp)) {
+ byte[] buf = new java.lang.String(Character.toChars(cp)).getBytes(UTF_8);
+ for (byte b : buf) {
+ r.append('=');
+ r.append(Integer.toHexString((b >>> 4) & 0x0f).toUpperCase());
+ r.append(Integer.toHexString(b & 0x0f).toUpperCase());
+ }
+
+ } else {
+ r.append(Character.toChars(cp));
+ }
+ }
+ r.append("?=");
+
+ return r.toString();
+ }
+
+ public static class Date extends EmailHeader {
+ private final java.util.Date value;
+
+ public Date(java.util.Date v) {
+ value = v;
+ }
+
+ public java.util.Date getDate() {
+ return value;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return value == null;
+ }
+
+ @Override
+ public void write(Writer w) throws IOException {
+ final SimpleDateFormat fmt;
+ // Mon, 1 Jun 2009 10:49:44 -0700
+ fmt = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US);
+ w.write(fmt.format(value));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof Date) && Objects.equals(value, ((Date) o).value);
+ }
+
+ @Override
+ public java.lang.String toString() {
+ return MoreObjects.toStringHelper(this).addValue(value).toString();
+ }
+ }
+
+ public static class AddressList extends EmailHeader {
+ private final List<Address> list = new ArrayList<>();
+
+ public AddressList() {}
+
+ public AddressList(Address addr) {
+ add(addr);
+ }
+
+ public List<Address> getAddressList() {
+ return Collections.unmodifiableList(list);
+ }
+
+ public void add(Address addr) {
+ list.add(addr);
+ }
+
+ public void remove(java.lang.String email) {
+ list.removeIf(address -> address.getEmail().equals(email));
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return list.isEmpty();
+ }
+
+ @Override
+ public void write(Writer w) throws IOException {
+ int len = 8;
+ boolean firstAddress = true;
+ boolean needComma = false;
+ for (Address addr : list) {
+ java.lang.String s = addr.toHeaderString();
+ if (firstAddress) {
+ firstAddress = false;
+ } else if (72 < len + s.length()) {
+ w.write(",\r\n\t");
+ len = 8;
+ needComma = false;
+ }
+
+ if (needComma) {
+ w.write(", ");
+ }
+ w.write(s);
+ len += s.length();
+ needComma = true;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(list);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof AddressList) && Objects.equals(list, ((AddressList) o).list);
+ }
+
+ @Override
+ public java.lang.String toString() {
+ return MoreObjects.toStringHelper(this).addValue(list).toString();
+ }
+ }
+}