· 9 years ago · Jan 11, 2017, 06:10 AM
1package gmailcontacts;
2
3import java.io.BufferedReader;
4import java.io.BufferedWriter;
5import java.io.File;
6import java.io.FileInputStream;
7import java.io.FileOutputStream;
8import java.io.InputStreamReader;
9import java.io.OutputStreamWriter;
10import java.io.UnsupportedEncodingException;
11import java.io.IOException;
12import java.util.HashMap;
13import java.util.TreeMap;
14import java.util.Map;
15
16public class GmailContacts {
17
18 // Define input and output file names
19 private static final String CT_OLD = "contactsOld.tsv",
20 CT_NEW = "contactsNew.tsv",
21 CT_GMAIL = "contactsGmail.tsv";
22
23 // Define file encoding (US-ASCII, UTF-8, etc.)
24 private static final String CT_ENCODING = "US-ASCII";
25
26 // Define sorting method for the output file
27 // 0 -> sort by first name, 1 -> sort by last name
28 private static final int SORT_METHOD = 0;
29
30 public static void main(String[] args) {
31 // Store contacts in a HashMap, using their names as the Key
32 Map<String, String> allContacts = new HashMap<>();
33 // Use a TreeMap here, which is automatically sorted by the Key
34 // In other words, the output is auto sorted
35 Map<String, String> gmailOnly = new TreeMap<>();
36
37 try {
38 // Make sure that both input files exist
39 File f1 = new File(CT_OLD);
40 File f2 = new File(CT_NEW);
41
42 if (!f1.isFile()) {
43 System.err.println("Error: Input file " + CT_OLD + " does not exist! Aborting.");
44 System.exit(1);
45 }
46 if (!f2.isFile()) {
47 System.err.println("Error: Input file " + CT_NEW + " does not exist! Aborting.");
48 System.exit(1);
49 }
50
51 // Read OLD contacts from file, and add them to 'allContacts'
52 allContacts = readTSV(CT_OLD);
53 // Read NEW contacts from file, and add them to 'allContacts'
54 // All duplicate contacts are replaced with their new details
55 allContacts.putAll(readTSV(CT_NEW));
56
57 // Filter out '@gmail.com' contacts from 'allContacts'
58 gmailOnly = getGmail(allContacts);
59
60 // Print results
61 for (Map.Entry<String, String> entry : gmailOnly.entrySet()) {
62 System.out.println(entry.getValue());
63 }
64
65 System.out.println();
66 System.out.println("Writing results to file " + CT_GMAIL + " ...");
67
68 // Write results to file
69 writeTSV(CT_GMAIL, gmailOnly);
70
71 } catch (Exception e) {
72 System.err.println(e.getMessage());
73 System.exit(1);
74 }
75 }
76
77 /**
78 *
79 * Filter out and return only those contacts with one or more
80 * email address matching '@gmail.com'
81 */
82 private static Map<String, String> getGmail(Map<String, String> data) {
83 // Use a TreeMap which is automatically sorted by the Key
84 Map<String, String> gmailOnly = new TreeMap<>();
85
86 try {
87 for (Map.Entry<String, String> entry : data.entrySet()) {
88 String[] newSplit = entry.getValue().split("\t");
89 // Check for existence of additional fields
90 if (newSplit.length >= 2) {
91 // In case there are multiple emails separated by comma,
92 // check if any matches '@gmail.com', except the last one
93 if (newSplit[newSplit.length - 1].toLowerCase().contains("@gmail.com,")) {
94 gmailOnly.put(entry.getKey(), entry.getValue());
95 // Check if the last email address matches '@gmail.com'
96 } else if (newSplit[newSplit.length - 1].trim().toLowerCase().endsWith("@gmail.com")) {
97 gmailOnly.put(entry.getKey(), entry.getValue());
98 }
99 }
100 }
101 } catch (Exception e) {
102 System.err.println(e.getMessage());
103 }
104 return gmailOnly;
105 }
106
107 /**
108 *
109 * Read TSV file 'tsvIn' and return results as a Map, with the first column
110 * (contact names) as the Key, and the entire line as the Value
111 */
112 private static Map<String, String> readTSV(String tsvIn) {
113 Map<String, String> data = new HashMap<>();
114 BufferedReader br = null;
115
116 try {
117 File file = new File(tsvIn);
118
119 br = new BufferedReader(
120 new InputStreamReader(
121 new FileInputStream(
122 file.getAbsoluteFile()), CT_ENCODING));
123 while (true) {
124 String newLine = br.readLine();
125 String fullName = null,
126 mapKey = null,
127 phoneNo = "",
128 emailAddr = "",
129 lastValue = null;
130 String[] lastSplit,
131 newSplit,
132 nameSplit;
133 if (newLine == null) {
134 // No more lines to read
135 break;
136 } else if (newLine.trim().length() > 0) {
137 // Split line at TABs
138 newSplit = newLine.split("\t");
139 fullName = newSplit[0];
140 // Determine the Map Key according to SORT_METHOD
141 if (SORT_METHOD == 0) {
142 mapKey = fullName;
143 } else {
144 // Split fullName at spaces
145 nameSplit = fullName.split(" +");
146 if (nameSplit.length > 1) {
147 // Add last name in front (for sorting by last name)
148 mapKey = nameSplit[nameSplit.length - 1] + fullName;
149 } else {
150 mapKey = fullName;
151 }
152 }
153 // Check for existence of phone number field
154 if (newSplit.length >= 2) {
155 phoneNo = newSplit[1];
156 }
157 // Check for existence of email field
158 if (newSplit.length >= 3) {
159 emailAddr = newSplit[2];
160 }
161
162 lastValue = data.put(mapKey, newLine);
163 // A duplicate Key (contact name) is found. We need to
164 // merge fields from these two records
165 // Skip if the two records are identical
166 if (lastValue != null && !lastValue.trim().equals(newLine.trim())) {
167 lastSplit = lastValue.split("\t");
168 // Check for existence of phone number field
169 if (lastSplit.length >= 2) {
170 if (!"".equals(phoneNo)) {
171 phoneNo = lastSplit[1] + "," + phoneNo;
172 } else {
173 phoneNo = lastSplit[1];
174 }
175 }
176 // Check for existence of email field
177 if (lastSplit.length >= 3) {
178 if (!"".equals(emailAddr)) {
179 emailAddr = lastSplit[2] + "," + emailAddr;
180 } else {
181 emailAddr = lastSplit[2];
182 }
183 }
184 // Add the merged record to Map 'data'
185 data.put(mapKey, fullName + "\t" + phoneNo + "\t" + emailAddr);
186 }
187 }
188 }
189 } catch (UnsupportedEncodingException e) {
190 System.err.println("An UnsupportedEncodingException was caught: " + e.getMessage());
191 } catch (IOException e) {
192 System.err.println("An IOException was caught: " + e.getMessage());
193 } catch (Exception e) {
194 System.err.println(e.getMessage());
195 } finally {
196 try {
197 if (br != null) {
198 br.close();
199 }
200 } catch (IOException e) {
201 System.err.println("An IOException was caught: " + e.getMessage());
202 }
203 }
204 return data;
205 }
206
207 /**
208 *
209 * Write to the TSV file 'tsvOut', using Values from input Map 'data' as
210 * each line in the output.
211 */
212 private static void writeTSV(String tsvOut, Map<String, String> data) {
213 BufferedWriter bw = null;
214
215 try {
216 File file = new File(tsvOut);
217
218 if (!file.exists()) {
219 file.createNewFile();
220 }
221
222 bw = new BufferedWriter(
223 new OutputStreamWriter(
224 new FileOutputStream(
225 file.getAbsoluteFile()), CT_ENCODING));
226
227 for (Map.Entry<String, String> entry : data.entrySet()) {
228 bw.write(entry.getValue());
229 bw.newLine();
230 }
231 System.out.println("All done!");
232
233 } catch (UnsupportedEncodingException e) {
234 System.err.println("An UnsupportedEncodingException was caught: " + e.getMessage());
235 } catch (IOException e) {
236 System.err.println("An IOException was caught: " + e.getMessage());
237 } catch (Exception e) {
238 System.err.println(e.getMessage());
239 } finally {
240 try {
241 if (bw != null) {
242 bw.flush();
243 bw.close();
244 }
245 } catch (IOException e) {
246 System.err.println("An IOException was caught: " + e.getMessage());
247 }
248 }
249 }
250}