001package com.hfg.util;
002
003import java.time.ZoneOffset;
004import java.util.HashMap;
005import java.util.Map;
006import java.util.Set;
007
008import com.hfg.xml.XMLName;
009import com.hfg.xml.XMLTag;
010
011//------------------------------------------------------------------------------
012/**
013 Container for user information.
014 <div>
015 @author J. Alex Taylor, hairyfatguy.com
016 </div>
017 */
018//------------------------------------------------------------------------------
019// com.hfg XML/HTML Coding Library
020//
021// This library is free software; you can redistribute it and/or
022// modify it under the terms of the GNU Lesser General Public
023// License as published by the Free Software Foundation; either
024// version 2.1 of the License, or (at your option) any later version.
025//
026// This library is distributed in the hope that it will be useful,
027// but WITHOUT ANY WARRANTY; without even the implied warranty of
028// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
029// Lesser General Public License for more details.
030//
031// You should have received a copy of the GNU Lesser General Public
032// License along with this library; if not, write to the Free Software
033// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
034//
035// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
036// jataylor@hairyfatguy.com
037//------------------------------------------------------------------------------
038
039public class UserImpl implements User
040{
041   private String mUID;
042   private String mName;
043   private String mFirstName;
044   private String mPreferredName;
045   private String mSurname;
046   private String mEmail;
047   private String mPhoneNumber;
048   private String mLocation;
049   private String mImageUrl;
050   private String mClientHost;
051   private String mClientHostIP;
052   private String mDomain;
053   private ZoneOffset mTimezoneOffset;
054   private Map<String, String> mFields;
055
056   private String mTagName = XML_USER;
057
058   private static final String XML_USER            = "User";
059   private static final String XML_UID             = "UID";
060   private static final String XML_EMAIL           = "Email";
061   private static final String XML_FIRST_NAME      = "FirstName";
062   private static final String XML_PREFERRED_NAME  = "PreferredName";
063   private static final String XML_NAME            = "Name";
064   private static final String XML_LOCATION        = "Location";
065   private static final String XML_IMAGE_URL       = "ImageUrl";
066   private static final String XML_CLIENT_HOST     = "ClientHost";
067   private static final String XML_DOMAIN          = "Domain";
068   private static final String XML_TIMEZONE_OFFSET = "TimezoneOffset";
069
070   private static final XMLName NAME_ATTR = new XMLName("name");
071
072   //###########################################################################
073   // CONSTRUCTORS
074   //###########################################################################
075
076   //--------------------------------------------------------------------------
077   public UserImpl()
078   {
079   }
080
081   //--------------------------------------------------------------------------
082   public UserImpl(XMLTag inXMLTag)
083   {
084      inXMLTag.verifyTagName(mTagName);
085
086      setUID(inXMLTag.getRequiredSubtagByName(XML_UID).getUnescapedContent());
087      setName(inXMLTag.getRequiredSubtagByName(XML_NAME).getUnescapedContent());
088      setImageUrl(inXMLTag.getRequiredSubtagByName(XML_IMAGE_URL).getUnescapedContent());
089
090      XMLTag emailTag = inXMLTag.getOptionalSubtagByName(XML_EMAIL);
091      if (emailTag != null)
092      {
093         setEmail(emailTag.getUnescapedContent());
094      }
095
096      XMLTag locationTag = inXMLTag.getOptionalSubtagByName(XML_LOCATION);
097      if (locationTag != null)
098      {
099         setLocation(locationTag.getUnescapedContent());
100      }
101
102      XMLTag clientHostTag = inXMLTag.getOptionalSubtagByName(XML_CLIENT_HOST);
103      if (clientHostTag != null)
104      {
105         setClientHostIP(clientHostTag.getUnescapedContent());
106         setClientHost(clientHostTag.getAttributeValue(NAME_ATTR));
107      }
108
109      XMLTag timezoneOffsetTag = inXMLTag.getOptionalSubtagByName(XML_TIMEZONE_OFFSET);
110      if (timezoneOffsetTag != null)
111      {
112         setTimezoneOffset(ZoneOffset.ofTotalSeconds(Integer.parseInt(timezoneOffsetTag.getUnescapedContent())));
113      }
114   }
115
116   //###########################################################################
117   // PUBLIC METHODS
118   //###########################################################################
119
120   //--------------------------------------------------------------------------
121   public XMLTag toXMLTag()
122   {
123      XMLTag parentTag = new XMLTag(XML_USER);
124
125      parentTag.addSubtag(new XMLTag(XML_UID).setContent(mUID));
126      parentTag.addSubtag(new XMLTag(XML_NAME).setContent(mName));
127      parentTag.addSubtag(new XMLTag(XML_IMAGE_URL).setContent(mImageUrl));
128
129      if (StringUtil.isSet(mFirstName))
130      {
131         parentTag.addSubtag(new XMLTag(XML_FIRST_NAME).setContent(mFirstName));
132      }
133
134      if (StringUtil.isSet(mPreferredName))
135      {
136         parentTag.addSubtag(new XMLTag(XML_PREFERRED_NAME).setContent(mPreferredName));
137      }
138
139      if (StringUtil.isSet(mEmail))
140      {
141         parentTag.addSubtag(new XMLTag(XML_EMAIL).setContent(mEmail));
142      }
143
144      if (StringUtil.isSet(mLocation))
145      {
146         parentTag.addSubtag(new XMLTag(XML_LOCATION).setContent(mLocation));
147      }
148
149      String clientHostIP = getClientHostIP();
150      String clientHost   = getClientHost();
151      if (StringUtil.isSet(clientHost)
152          || StringUtil.isSet(clientHostIP))
153      {
154         XMLTag clientHostTag = parentTag.addSubtag(XML_CLIENT_HOST);
155         if (StringUtil.isSet(clientHostIP))
156         {
157            clientHostTag.setContent(clientHostIP);
158         }
159
160         if (StringUtil.isSet(clientHost))
161         {
162            clientHostTag.setAttribute(NAME_ATTR, clientHost);
163         }
164      }
165
166      if (mTimezoneOffset != null)
167      {
168         parentTag.addSubtag(new XMLTag(XML_TIMEZONE_OFFSET).setContent(mTimezoneOffset.getTotalSeconds()));
169      }
170
171      return parentTag;
172   }
173
174   //--------------------------------------------------------------------------
175   @Override
176   public String toString()
177   {
178      return getName();
179   }
180
181   //--------------------------------------------------------------------------
182   public UserImpl setUID(String inValue)
183   {
184      mUID = inValue;
185      return this;
186   }
187
188   //--------------------------------------------------------------------------
189   public String getUID()
190   {
191      return mUID;
192   }
193
194
195   //--------------------------------------------------------------------------
196   public UserImpl setName(String inValue)
197   {
198      mName = inValue;
199
200      // Make an attempt to set the first name and surname values
201      if (StringUtil.isSet(mName)
202          && (null == mSurname
203              || null == mFirstName))
204      {
205         if (mName.contains(","))
206         {
207            String[] pieces = mName.split(",");
208            if (pieces.length > 1)
209            {
210               if (null == mSurname)
211               {
212                  String[] surnamePieces = pieces[0].split("\\s+");
213
214                  StringBuilderPlus surname = new StringBuilderPlus().setDelimiter(" ");
215                  for (int i = 0; i < surnamePieces.length; i++)
216                  {
217                     String piece = surnamePieces[i].trim();
218                     if (! piece.startsWith("("))
219                     {
220                        surname.delimitedAppend(piece);
221                     }
222                  }
223
224                  mSurname = surname.toString();
225               }
226
227               if (null == mFirstName) setFirstName(pieces[1].trim());
228            }
229         }
230         else
231         {
232            String[] pieces = mName.split("\\s+");
233            if (pieces.length > 1)
234            {
235               if (null == mFirstName) setFirstName(pieces[0].trim());
236
237               if (null == mSurname)
238               {
239                  StringBuilderPlus surname = new StringBuilderPlus().setDelimiter(" ");
240                  for (int i = 1; i < pieces.length; i++)
241                  {
242                     String piece = pieces[i].trim();
243                     if (! piece.startsWith("("))
244                     {
245                        surname.delimitedAppend(piece);
246                     }
247                  }
248
249                  mSurname = surname.toString();
250               }
251            }
252         }
253      }
254
255      return this;
256   }
257
258   //--------------------------------------------------------------------------
259   public String getName()
260   {
261      if (null == mName)
262      {
263         StringBuilderPlus name = new StringBuilderPlus().setDelimiter(" ");
264
265         if (StringUtil.isSet(getPreferredName()))
266         {
267            name.append(getPreferredName());
268         }
269         else if (StringUtil.isSet(getFirstName()))
270         {
271            name.append(getFirstName());
272         }
273
274         if (StringUtil.isSet(getSurname()))
275         {
276            name.delimitedAppend(getSurname());
277         }
278
279         if (name.length() > 0)
280         {
281            mName = name.toString();
282         }
283      }
284      return mName;
285   }
286
287
288   //--------------------------------------------------------------------------
289   public UserImpl setFirstName(String inValue)
290   {
291      mFirstName = inValue;
292      return this;
293   }
294
295   //--------------------------------------------------------------------------
296   public String getFirstName()
297   {
298      return mFirstName;
299   }
300
301
302   //--------------------------------------------------------------------------
303   public UserImpl setPreferredName(String inValue)
304   {
305      mPreferredName = inValue;
306      return this;
307   }
308
309   //--------------------------------------------------------------------------
310   public String getPreferredName()
311   {
312      return mPreferredName;
313   }
314
315
316   //--------------------------------------------------------------------------
317   public UserImpl setSurname(String inValue)
318   {
319      mSurname = inValue;
320      return this;
321   }
322
323   //--------------------------------------------------------------------------
324   public String getSurname()
325   {
326      return mSurname;
327   }
328
329
330   //--------------------------------------------------------------------------
331   public UserImpl setDomain(String inValue)
332   {
333      mDomain = inValue;
334      return this;
335   }
336
337   //--------------------------------------------------------------------------
338   public String getDomain()
339   {
340      return mDomain;
341   }
342
343
344   //--------------------------------------------------------------------------
345   public UserImpl setEmail(String inValue)
346   {
347      mEmail = inValue;
348
349      if (mEmail != null
350            && null == mDomain)
351      {
352         int index = mEmail.indexOf("@");
353         setDomain(mEmail.substring(index + 1));
354      }
355
356      return this;
357   }
358
359   //--------------------------------------------------------------------------
360   public String getEmail()
361   {
362      return mEmail;
363   }
364
365
366   //--------------------------------------------------------------------------
367   public UserImpl setPhoneNumber(String inValue)
368   {
369      mPhoneNumber = inValue;
370      return this;
371   }
372
373   //--------------------------------------------------------------------------
374   public String getPhoneNumber()
375   {
376      return mPhoneNumber;
377   }
378
379
380   //--------------------------------------------------------------------------
381   public UserImpl setLocation(String inValue)
382   {
383      mLocation = inValue;
384      return this;
385   }
386
387   //--------------------------------------------------------------------------
388   public String getLocation() { return mLocation; }
389
390
391   //--------------------------------------------------------------------------
392   public UserImpl setImageUrl(String inValue)
393   {
394      mImageUrl = inValue;
395      return this;
396   }
397
398   //--------------------------------------------------------------------------
399   public String getImageUrl()
400   {
401      return mImageUrl;
402   }
403
404   //--------------------------------------------------------------------------
405   public UserImpl setClientHost(String inValue)
406   {
407      mClientHost = inValue;
408      return this;
409   }
410
411   //--------------------------------------------------------------------------
412   public String getClientHost()
413   {
414      return mClientHost;
415   }
416
417
418   //--------------------------------------------------------------------------
419   public UserImpl setClientHostIP(String inValue)
420   {
421      mClientHostIP = inValue;
422      return this;
423   }
424
425   //--------------------------------------------------------------------------
426   public String getClientHostIP()
427   {
428      return mClientHostIP;
429   }
430
431   
432   //--------------------------------------------------------------------------
433   public UserImpl setTimezoneOffset(ZoneOffset inValue)
434   {
435      mTimezoneOffset = inValue;
436      return this;
437   }
438
439   //--------------------------------------------------------------------------
440   public ZoneOffset getTimezoneOffset()
441   {
442      return mTimezoneOffset;
443   }
444
445   //--------------------------------------------------------------------------
446   public UserImpl setField(String inName, String inValue)
447   {
448      if (null == mFields)
449      {
450         mFields = new HashMap<>(20);
451      }
452
453      mFields.put(inName, inValue);
454
455      return this;
456   }
457
458   //--------------------------------------------------------------------------
459   public String getField(String inName)
460   {
461      return (mFields != null ? mFields.get(inName) : null);
462   }
463
464   //--------------------------------------------------------------------------
465   public Set<String> getFieldNames()
466   {
467      return mFields.keySet();
468   }
469
470   //--------------------------------------------------------------------------
471   @Override
472   public int hashCode()
473   {
474      String name = getName();
475      int result = (StringUtil.isSet(name) ? name.hashCode() : 0);
476
477      String uid = getUID();
478      if (uid != null)
479      {
480         result += 31 * uid.hashCode();
481      }
482
483      return result;
484   }
485
486   //--------------------------------------------------------------------------
487   @Override
488   public boolean equals(Object inObj2)
489   {
490      return (0 == compareTo(inObj2));
491   }
492
493   //--------------------------------------------------------------------------
494   @Override
495   public int compareTo(Object inObj2)
496   {
497      int result = -1;
498      if (inObj2 != null
499          && inObj2 instanceof User)
500      {
501         result = CompareUtil.compare(getName(), ((User) inObj2).getName());
502
503         if (0 == result)
504         {
505            result = CompareUtil.compare(getUID(), ((User) inObj2).getUID());
506         }
507      }
508
509      return result;
510   }
511}