001: // The contents of this file are subject to the Mozilla Public License Version
002: // 1.1
003: //(the "License"); you may not use this file except in compliance with the
004: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
005: //
006: //Software distributed under the License is distributed on an "AS IS" basis,
007: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
008: //for the specific language governing rights and
009: //limitations under the License.
010: //
011: //The Original Code is "The Columba Project"
012: //
013: //The Initial Developers of the Original Code are Frederik Dietz and Timo
014: // Stich.
015: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
016: //
017: //All Rights Reserved.
018: package org.columba.core.util;
019:
020: import java.util.ArrayList;
021: import java.util.List;
022: import java.util.StringTokenizer;
023:
024: import org.columba.core.resourceloader.GlobalResourceLoader;
025:
026: /**
027: * Used to parse display names, e.g. John Doe, John Q. Public, Dr.
028: * @author Rick Horowitz
029: *
030: */
031: public class NameParser {
032:
033: public static void main(String args[]) {
034: String[] testNames = { "Dr. Richard K. Ellington", "Bob Jones",
035: "Ms. Jill Hark", "Robert B. Smith, Esq.",
036: "Johnson, PhD.", "Sue & Gene Stark", "George", "", null };
037: NameParser parser = NameParser.getInstance();
038: for (int i = 0; i < testNames.length; i++) {
039: String name = testNames[i];
040: System.out.println(i + ": "
041: + parser.parseDisplayName(name).toString());
042: }
043: }
044:
045: private static final String RESOURCE_PATH = "org.columba.core.i18n.global";
046:
047: /** Salutations used at the beginning of a display name. */
048: // private static final String[] SALUTATIONS = { "Mr.", "Mrs.", "Ms.", "Dr.", "Congressman", "Congresswoman", "Senator", "President",
049: // "Chancellor", "Minister", "Prime Minister" };
050: /** Titles used at the end of a display name. */
051: // private static final String[] TITLES = { "PhD", "Ph.D.", "PhD.", "Esq.", "Esquire" };
052: private static NameParser _instance;
053:
054: /**
055: * Get the singleton instance of NameParser
056: * @return NameParser instance.
057: */
058: public static NameParser getInstance() {
059: if (_instance == null)
060: _instance = new NameParser();
061: return _instance;
062: }
063:
064: /** Salutations used at the beginning of a display name. */
065: private final String[] SALUTATIONS;
066: /** Titles used at the end of a display name. */
067: private final String[] TITLES;
068:
069: /**
070: * Construct a singleton instance
071: */
072: private NameParser() {
073:
074: // Initialize salutation strings
075: List<String> salutations = new ArrayList<String>();
076: String salutationsStr = GlobalResourceLoader.getString(
077: RESOURCE_PATH, "global", "name_parser_salutations");
078: StringTokenizer st = new StringTokenizer(salutationsStr, ",");
079: while (st.hasMoreTokens()) {
080: salutations.add(st.nextToken());
081: }
082: SALUTATIONS = salutations
083: .toArray(new String[salutations.size()]);
084:
085: // Initialize title strings
086: List<String> titles = new ArrayList<String>();
087: String titlesStr = GlobalResourceLoader.getString(
088: RESOURCE_PATH, "global", "name_parser_titles");
089: st = new StringTokenizer(titlesStr, ",");
090: while (st.hasMoreTokens()) {
091: titles.add(st.nextToken());
092: }
093: TITLES = titles.toArray(new String[titles.size()]);
094:
095: }
096:
097: public Name parseDisplayName(String nameInputStr) {
098:
099: // Treat a null name input string the same as an empty input string
100: if (nameInputStr == null)
101: nameInputStr = "";
102:
103: String displayName = nameInputStr;
104: String salutation = null;
105: String firstName = null;
106: String middleName = null;
107: String lastName = null;
108: String title = null;
109:
110: // Get the salutation if one is specified
111: salutation = findSalutation(nameInputStr);
112: if (salutation != null) {
113: // Remove the salutation
114: nameInputStr = nameInputStr.substring(salutation.length());
115: }
116:
117: // Get the title if one is specified
118: title = findTitle(nameInputStr);
119: if (title != null) {
120: // Remove the title and the preceding comma
121: nameInputStr = nameInputStr.substring(0, nameInputStr
122: .length()
123: - title.length());
124: nameInputStr = nameInputStr.substring(0, nameInputStr
125: .lastIndexOf(','));
126: }
127:
128: // Determine whether there are 1, 2, or 3 names specified. These names should be separated by spaces
129: // or commas. If a comma separates the first two names, assume that the last name is specified first,
130: // Otherwise, assume the first name is specified first. Middle name is always specified after the first name.
131: StringTokenizer st = new StringTokenizer(nameInputStr, ", ");
132: List<String> tokens = new ArrayList<String>();
133: while (st.hasMoreTokens()) {
134: tokens.add(st.nextToken());
135: }
136:
137: boolean commaSpecified = nameInputStr.indexOf(',') >= 0;
138: if (tokens.size() == 0) {
139: // Do nothing
140: } else if (tokens.size() == 1) {
141: // Assume last name only
142: lastName = tokens.get(0);
143: } else if (tokens.size() == 2) {
144: if (commaSpecified) {
145: lastName = tokens.get(0);
146: firstName = tokens.get(1);
147: } else {
148: firstName = tokens.get(0);
149: lastName = tokens.get(1);
150: }
151: } else if (tokens.size() == 3) {
152: if (commaSpecified) {
153: lastName = tokens.get(0);
154: firstName = tokens.get(1);
155: middleName = tokens.get(2);
156: } else {
157: firstName = tokens.get(0);
158: middleName = tokens.get(1);
159: lastName = tokens.get(2);
160: }
161: } else {
162: // More than 3 tokens. Assume the last token is the last name and take the rest of the names as the first name.
163: // This handles names like this: "Sue & Gene Stark".
164: StringBuffer firstSB = new StringBuffer();
165: lastName = (String) tokens.get(tokens.size() - 1);
166: firstName = nameInputStr.substring(0,
167: nameInputStr.length() - lastName.length()).trim();
168: }
169:
170: return new Name(displayName, salutation, firstName, middleName,
171: lastName, title);
172: }
173:
174: /**
175: * Find the title in the "nameInputStr", if one exists. Searches the salutations including in
176: * NameParser.TITLES.
177: * @param nameInputStr The display name to search.
178: * @return The title, or null, if none is found.
179: */
180: private String findTitle(String nameInputStr) {
181: String title = null;
182: for (String s : TITLES) {
183: if (nameInputStr.endsWith(s)) {
184: title = s;
185: break;
186: }
187: }
188: return title;
189: }
190:
191: /**
192: * Find the salutation in the "nameInputStr", if one exists. Searches the salutations including in
193: * NameParser.SALUTATIONS.
194: * @param nameInputStr The display name to search.
195: * @return The salutation, or null, if none is found.
196: */
197: private String findSalutation(String nameInputStr) {
198: String salutation = null;
199: for (String s : SALUTATIONS) {
200: if (nameInputStr.startsWith(s)) {
201: salutation = s;
202: break;
203: }
204: }
205: return salutation;
206: }
207:
208: /**
209: * The parsed name.
210: */
211: public static class Name {
212: private String _displayName;
213: private String _firstName;
214: private String _middleName;
215: private String _lastName;
216: private String _salutation;
217: private String _title;
218:
219: public Name(String displayName, String salutation,
220: String firstName, String middleName, String lastName,
221: String title) {
222: _displayName = displayName;
223: _salutation = salutation;
224: _firstName = firstName;
225: _middleName = middleName;
226: _lastName = lastName;
227: _title = title;
228: }
229:
230: /**
231: * @return the displayName
232: */
233: public String getDisplayName() {
234: return _displayName;
235: }
236:
237: /**
238: * @return the first name
239: */
240: public String getFirstName() {
241: return _firstName;
242: }
243:
244: /**
245: * @return the last name
246: */
247: public String getLastName() {
248: return _lastName;
249: }
250:
251: /**
252: * @return the middle name
253: */
254: public String getMiddleName() {
255: return _middleName;
256: }
257:
258: /**
259: * @return the salutation, e.g. Mr., Ms., Dr., etc.
260: */
261: public String getSalutation() {
262: return _salutation;
263: }
264:
265: /**
266: * @return the title, e.g. PhD, Esquire, Senator, etc.
267: */
268: public String getTitle() {
269: return _title;
270: }
271:
272: /* (non-Javadoc)
273: * @see java.lang.Object#toString()
274: */
275: public String toString() {
276: StringBuffer sb = new StringBuffer();
277: if (_salutation != null) {
278: sb.append(_salutation);
279: sb.append(" ");
280: }
281: if (_firstName != null) {
282: sb.append(_firstName);
283: sb.append(" ");
284: }
285: if (_middleName != null) {
286: sb.append(_middleName);
287: sb.append(" ");
288: }
289: if (_lastName != null) {
290: sb.append(_lastName);
291: }
292: if (_title != null) {
293: sb.append(", ");
294: sb.append(_title);
295: }
296:
297: return sb.toString();
298: }
299: }
300:
301: }
|