001
014
015 package com.liferay.portal.model.impl;
016
017 import com.liferay.portal.kernel.bean.AutoEscape;
018 import com.liferay.portal.kernel.dao.orm.QueryUtil;
019 import com.liferay.portal.kernel.dao.shard.ShardUtil;
020 import com.liferay.portal.kernel.exception.PortalException;
021 import com.liferay.portal.kernel.exception.SystemException;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.util.Digester;
025 import com.liferay.portal.kernel.util.DigesterUtil;
026 import com.liferay.portal.kernel.util.HtmlUtil;
027 import com.liferay.portal.kernel.util.LocaleUtil;
028 import com.liferay.portal.kernel.util.PropsKeys;
029 import com.liferay.portal.kernel.util.RemotePreference;
030 import com.liferay.portal.kernel.util.SetUtil;
031 import com.liferay.portal.kernel.util.StringBundler;
032 import com.liferay.portal.kernel.util.StringPool;
033 import com.liferay.portal.kernel.util.StringUtil;
034 import com.liferay.portal.kernel.util.TimeZoneUtil;
035 import com.liferay.portal.kernel.util.Validator;
036 import com.liferay.portal.kernel.workflow.WorkflowConstants;
037 import com.liferay.portal.model.Address;
038 import com.liferay.portal.model.Company;
039 import com.liferay.portal.model.CompanyConstants;
040 import com.liferay.portal.model.Contact;
041 import com.liferay.portal.model.EmailAddress;
042 import com.liferay.portal.model.Group;
043 import com.liferay.portal.model.Organization;
044 import com.liferay.portal.model.PasswordPolicy;
045 import com.liferay.portal.model.Phone;
046 import com.liferay.portal.model.Role;
047 import com.liferay.portal.model.Team;
048 import com.liferay.portal.model.UserConstants;
049 import com.liferay.portal.model.UserGroup;
050 import com.liferay.portal.model.Website;
051 import com.liferay.portal.security.auth.EmailAddressGenerator;
052 import com.liferay.portal.security.auth.EmailAddressGeneratorFactory;
053 import com.liferay.portal.security.auth.FullNameGenerator;
054 import com.liferay.portal.security.auth.FullNameGeneratorFactory;
055 import com.liferay.portal.service.AddressLocalServiceUtil;
056 import com.liferay.portal.service.CompanyLocalServiceUtil;
057 import com.liferay.portal.service.ContactLocalServiceUtil;
058 import com.liferay.portal.service.EmailAddressLocalServiceUtil;
059 import com.liferay.portal.service.GroupLocalServiceUtil;
060 import com.liferay.portal.service.GroupServiceUtil;
061 import com.liferay.portal.service.LayoutLocalServiceUtil;
062 import com.liferay.portal.service.OrganizationLocalServiceUtil;
063 import com.liferay.portal.service.PasswordPolicyLocalServiceUtil;
064 import com.liferay.portal.service.PhoneLocalServiceUtil;
065 import com.liferay.portal.service.RoleLocalServiceUtil;
066 import com.liferay.portal.service.TeamLocalServiceUtil;
067 import com.liferay.portal.service.UserGroupLocalServiceUtil;
068 import com.liferay.portal.service.WebsiteLocalServiceUtil;
069 import com.liferay.portal.theme.ThemeDisplay;
070 import com.liferay.portal.util.Portal;
071 import com.liferay.portal.util.PortalUtil;
072 import com.liferay.portal.util.PrefsPropsUtil;
073 import com.liferay.portal.util.PropsUtil;
074 import com.liferay.portal.util.PropsValues;
075
076 import java.util.Collection;
077 import java.util.Collections;
078 import java.util.Date;
079 import java.util.HashMap;
080 import java.util.List;
081 import java.util.Locale;
082 import java.util.Map;
083 import java.util.Set;
084 import java.util.TimeZone;
085 import java.util.TreeSet;
086
087
092 public class UserImpl extends UserBaseImpl {
093
094 public UserImpl() {
095 }
096
097 @Override
098 public void addRemotePreference(RemotePreference remotePreference) {
099 _remotePreferences.put(remotePreference.getName(), remotePreference);
100 }
101
102 @Override
103 public List<Address> getAddresses() throws SystemException {
104 return AddressLocalServiceUtil.getAddresses(
105 getCompanyId(), Contact.class.getName(), getContactId());
106 }
107
108 @Override
109 public Date getBirthday() throws PortalException, SystemException {
110 return getContact().getBirthday();
111 }
112
113 @Override
114 public String getCompanyMx() throws PortalException, SystemException {
115 Company company = CompanyLocalServiceUtil.getCompanyById(
116 getCompanyId());
117
118 return company.getMx();
119 }
120
121 @Override
122 public Contact getContact() throws PortalException, SystemException {
123 try {
124 ShardUtil.pushCompanyService(getCompanyId());
125
126 return ContactLocalServiceUtil.getContact(getContactId());
127 }
128 finally {
129 ShardUtil.popCompanyService();
130 }
131 }
132
133 @Override
134 public String getDigest() {
135 String digest = super.getDigest();
136
137 if (Validator.isNull(digest) && !isPasswordEncrypted()) {
138 digest = getDigest(getPassword());
139 }
140
141 return digest;
142 }
143
144 @Override
145 public String getDigest(String password) {
146 if (Validator.isNull(getScreenName())) {
147 throw new IllegalStateException("Screen name is null");
148 }
149 else if (Validator.isNull(getEmailAddress())) {
150 throw new IllegalStateException("Email address is null");
151 }
152
153 StringBundler sb = new StringBundler(5);
154
155 String digest1 = DigesterUtil.digestHex(
156 Digester.MD5, getEmailAddress(), Portal.PORTAL_REALM, password);
157
158 sb.append(digest1);
159 sb.append(StringPool.COMMA);
160
161 String digest2 = DigesterUtil.digestHex(
162 Digester.MD5, getScreenName(), Portal.PORTAL_REALM, password);
163
164 sb.append(digest2);
165 sb.append(StringPool.COMMA);
166
167 String digest3 = DigesterUtil.digestHex(
168 Digester.MD5, String.valueOf(getUserId()), Portal.PORTAL_REALM,
169 password);
170
171 sb.append(digest3);
172
173 return sb.toString();
174 }
175
176 @Override
177 public String getDisplayEmailAddress() {
178 String emailAddress = super.getEmailAddress();
179
180 EmailAddressGenerator emailAddressGenerator =
181 EmailAddressGeneratorFactory.getInstance();
182
183 if (emailAddressGenerator.isFake(emailAddress)) {
184 emailAddress = StringPool.BLANK;
185 }
186
187 return emailAddress;
188 }
189
190 @Override
191 public String getDisplayURL(String portalURL, String mainPath)
192 throws PortalException, SystemException {
193
194 return getDisplayURL(portalURL, mainPath, false);
195 }
196
197 @Override
198 public String getDisplayURL(
199 String portalURL, String mainPath, boolean privateLayout)
200 throws PortalException, SystemException {
201
202 if (isDefaultUser()) {
203 return StringPool.BLANK;
204 }
205
206 String profileFriendlyURL = getProfileFriendlyURL();
207
208 if (Validator.isNotNull(profileFriendlyURL)) {
209 return portalURL.concat(PortalUtil.getPathContext()).concat(
210 profileFriendlyURL);
211 }
212
213 Group group = getGroup();
214
215 int publicLayoutsPageCount = group.getPublicLayoutsPageCount();
216
217 if (publicLayoutsPageCount > 0) {
218 StringBundler sb = new StringBundler(5);
219
220 sb.append(portalURL);
221 sb.append(mainPath);
222 sb.append("/my_sites/view?groupId=");
223 sb.append(group.getGroupId());
224
225 if (privateLayout) {
226 sb.append("&privateLayout=1");
227 }
228 else {
229 sb.append("&privateLayout=0");
230 }
231
232 return sb.toString();
233 }
234
235 return StringPool.BLANK;
236 }
237
238 @Override
239 public String getDisplayURL(ThemeDisplay themeDisplay)
240 throws PortalException, SystemException {
241
242 return getDisplayURL(
243 themeDisplay.getPortalURL(), themeDisplay.getPathMain(), false);
244 }
245
246 @Override
247 public String getDisplayURL(
248 ThemeDisplay themeDisplay, boolean privateLayout)
249 throws PortalException, SystemException {
250
251 return getDisplayURL(
252 themeDisplay.getPortalURL(), themeDisplay.getPathMain(),
253 privateLayout);
254 }
255
256 @Override
257 public List<EmailAddress> getEmailAddresses() throws SystemException {
258 return EmailAddressLocalServiceUtil.getEmailAddresses(
259 getCompanyId(), Contact.class.getName(), getContactId());
260 }
261
262 @Override
263 public boolean getFemale() throws PortalException, SystemException {
264 return !getMale();
265 }
266
267 @AutoEscape
268 @Override
269 public String getFullName() {
270 FullNameGenerator fullNameGenerator =
271 FullNameGeneratorFactory.getInstance();
272
273 return fullNameGenerator.getFullName(
274 getFirstName(), getMiddleName(), getLastName());
275 }
276
277 @Override
278 public Group getGroup() throws PortalException, SystemException {
279 return GroupLocalServiceUtil.getUserGroup(getCompanyId(), getUserId());
280 }
281
282 @Override
283 public long getGroupId() throws PortalException, SystemException {
284 Group group = getGroup();
285
286 return group.getGroupId();
287 }
288
289 @Override
290 public long[] getGroupIds() throws SystemException {
291 List<Group> groups = getGroups();
292
293 long[] groupIds = new long[groups.size()];
294
295 for (int i = 0; i < groups.size(); i++) {
296 Group group = groups.get(i);
297
298 groupIds[i] = group.getGroupId();
299 }
300
301 return groupIds;
302 }
303
304 @Override
305 public List<Group> getGroups() throws SystemException {
306 return GroupLocalServiceUtil.getUserGroups(getUserId());
307 }
308
309 @Override
310 public Locale getLocale() {
311 return _locale;
312 }
313
314 @Override
315 public String getLogin() throws PortalException, SystemException {
316 String login = null;
317
318 Company company = CompanyLocalServiceUtil.getCompanyById(
319 getCompanyId());
320
321 if (company.getAuthType().equals(CompanyConstants.AUTH_TYPE_EA)) {
322 login = getEmailAddress();
323 }
324 else if (company.getAuthType().equals(CompanyConstants.AUTH_TYPE_SN)) {
325 login = getScreenName();
326 }
327 else if (company.getAuthType().equals(CompanyConstants.AUTH_TYPE_ID)) {
328 login = String.valueOf(getUserId());
329 }
330
331 return login;
332 }
333
334 @Override
335 public boolean getMale() throws PortalException, SystemException {
336 return getContact().getMale();
337 }
338
339 @Override
340 public List<Group> getMySiteGroups()
341 throws PortalException, SystemException {
342
343 return getMySiteGroups(null, false, QueryUtil.ALL_POS);
344 }
345
346 @Override
347 public List<Group> getMySiteGroups(boolean includeControlPanel, int max)
348 throws PortalException, SystemException {
349
350 return getMySiteGroups(null, includeControlPanel, max);
351 }
352
353 @Override
354 public List<Group> getMySiteGroups(int max)
355 throws PortalException, SystemException {
356
357 return getMySiteGroups(null, false, max);
358 }
359
360 @Override
361 public List<Group> getMySiteGroups(
362 String[] classNames, boolean includeControlPanel, int max)
363 throws PortalException, SystemException {
364
365 return GroupServiceUtil.getUserSitesGroups(
366 getUserId(), classNames, includeControlPanel, max);
367 }
368
369 @Override
370 public List<Group> getMySiteGroups(String[] classNames, int max)
371 throws PortalException, SystemException {
372
373 return getMySiteGroups(classNames, false, max);
374 }
375
376
379 @Override
380 public List<Group> getMySites() throws PortalException, SystemException {
381 return getMySiteGroups();
382 }
383
384
388 @Override
389 public List<Group> getMySites(boolean includeControlPanel, int max)
390 throws PortalException, SystemException {
391
392 return getMySiteGroups(includeControlPanel, max);
393 }
394
395
398 @Override
399 public List<Group> getMySites(int max)
400 throws PortalException, SystemException {
401
402 return getMySiteGroups(max);
403 }
404
405
409 @Override
410 public List<Group> getMySites(
411 String[] classNames, boolean includeControlPanel, int max)
412 throws PortalException, SystemException {
413
414 return getMySiteGroups(classNames, includeControlPanel, max);
415 }
416
417
421 @Override
422 public List<Group> getMySites(String[] classNames, int max)
423 throws PortalException, SystemException {
424
425 return getMySiteGroups(classNames, max);
426 }
427
428 @Override
429 public long[] getOrganizationIds() throws PortalException, SystemException {
430 return getOrganizationIds(false);
431 }
432
433 @Override
434 public long[] getOrganizationIds(boolean includeAdministrative)
435 throws PortalException, SystemException {
436
437 List<Organization> organizations = getOrganizations(
438 includeAdministrative);
439
440 long[] organizationIds = new long[organizations.size()];
441
442 for (int i = 0; i < organizations.size(); i++) {
443 Organization organization = organizations.get(i);
444
445 organizationIds[i] = organization.getOrganizationId();
446 }
447
448 return organizationIds;
449 }
450
451 @Override
452 public List<Organization> getOrganizations()
453 throws PortalException, SystemException {
454
455 return getOrganizations(false);
456 }
457
458 @Override
459 public List<Organization> getOrganizations(boolean includeAdministrative)
460 throws PortalException, SystemException {
461
462 return OrganizationLocalServiceUtil.getUserOrganizations(
463 getUserId(), includeAdministrative);
464 }
465
466 @Override
467 public boolean getPasswordModified() {
468 return _passwordModified;
469 }
470
471 @Override
472 public PasswordPolicy getPasswordPolicy()
473 throws PortalException, SystemException {
474
475 if (_passwordPolicy == null) {
476 _passwordPolicy =
477 PasswordPolicyLocalServiceUtil.getPasswordPolicyByUserId(
478 getUserId());
479 }
480
481 return _passwordPolicy;
482 }
483
484 @Override
485 public String getPasswordUnencrypted() {
486 return _passwordUnencrypted;
487 }
488
489 @Override
490 public List<Phone> getPhones() throws SystemException {
491 return PhoneLocalServiceUtil.getPhones(
492 getCompanyId(), Contact.class.getName(), getContactId());
493 }
494
495 @Override
496 public String getPortraitURL(ThemeDisplay themeDisplay)
497 throws PortalException, SystemException {
498
499 return UserConstants.getPortraitURL(
500 themeDisplay.getPathImage(), isMale(), getPortraitId());
501 }
502
503 @Override
504 public int getPrivateLayoutsPageCount()
505 throws PortalException, SystemException {
506
507 return LayoutLocalServiceUtil.getLayoutsCount(this, true);
508 }
509
510 @Override
511 public int getPublicLayoutsPageCount()
512 throws PortalException, SystemException {
513
514 return LayoutLocalServiceUtil.getLayoutsCount(this, false);
515 }
516
517 @Override
518 public Set<String> getReminderQueryQuestions()
519 throws PortalException, SystemException {
520
521 Set<String> questions = new TreeSet<String>();
522
523 List<Organization> organizations =
524 OrganizationLocalServiceUtil.getUserOrganizations(getUserId());
525
526 for (Organization organization : organizations) {
527 Set<String> organizationQuestions =
528 organization.getReminderQueryQuestions(getLanguageId());
529
530 if (organizationQuestions.size() == 0) {
531 Organization parentOrganization =
532 organization.getParentOrganization();
533
534 while ((organizationQuestions.size() == 0) &&
535 (parentOrganization != null)) {
536
537 organizationQuestions =
538 parentOrganization.getReminderQueryQuestions(
539 getLanguageId());
540
541 parentOrganization =
542 parentOrganization.getParentOrganization();
543 }
544 }
545
546 questions.addAll(organizationQuestions);
547 }
548
549 if (questions.size() == 0) {
550 Set<String> defaultQuestions = SetUtil.fromArray(
551 PropsUtil.getArray(PropsKeys.USERS_REMINDER_QUERIES_QUESTIONS));
552
553 questions.addAll(defaultQuestions);
554 }
555
556 return questions;
557 }
558
559 @Override
560 public RemotePreference getRemotePreference(String name) {
561 return _remotePreferences.get(name);
562 }
563
564 @Override
565 public Iterable<RemotePreference> getRemotePreferences() {
566 Collection<RemotePreference> values = _remotePreferences.values();
567
568 return Collections.unmodifiableCollection(values);
569 }
570
571 @Override
572 public long[] getRoleIds() throws SystemException {
573 List<Role> roles = getRoles();
574
575 long[] roleIds = new long[roles.size()];
576
577 for (int i = 0; i < roles.size(); i++) {
578 Role role = roles.get(i);
579
580 roleIds[i] = role.getRoleId();
581 }
582
583 return roleIds;
584 }
585
586 @Override
587 public List<Role> getRoles() throws SystemException {
588 return RoleLocalServiceUtil.getUserRoles(getUserId());
589 }
590
591 @Override
592 public List<Group> getSiteGroups() throws PortalException, SystemException {
593 return getSiteGroups(false);
594 }
595
596 @Override
597 public List<Group> getSiteGroups(boolean includeAdministrative)
598 throws PortalException, SystemException {
599
600 return GroupLocalServiceUtil.getUserSitesGroups(
601 getUserId(), includeAdministrative);
602 }
603
604 @Override
605 public long[] getTeamIds() throws SystemException {
606 List<Team> teams = getTeams();
607
608 long[] teamIds = new long[teams.size()];
609
610 for (int i = 0; i < teams.size(); i++) {
611 Team team = teams.get(i);
612
613 teamIds[i] = team.getTeamId();
614 }
615
616 return teamIds;
617 }
618
619 @Override
620 public List<Team> getTeams() throws SystemException {
621 return TeamLocalServiceUtil.getUserTeams(getUserId());
622 }
623
624 @Override
625 public TimeZone getTimeZone() {
626 return _timeZone;
627 }
628
629 @Override
630 public long[] getUserGroupIds() throws SystemException {
631 List<UserGroup> userGroups = getUserGroups();
632
633 long[] userGroupIds = new long[userGroups.size()];
634
635 for (int i = 0; i < userGroups.size(); i++) {
636 UserGroup userGroup = userGroups.get(i);
637
638 userGroupIds[i] = userGroup.getUserGroupId();
639 }
640
641 return userGroupIds;
642 }
643
644 @Override
645 public List<UserGroup> getUserGroups() throws SystemException {
646 return UserGroupLocalServiceUtil.getUserUserGroups(getUserId());
647 }
648
649 @Override
650 public List<Website> getWebsites() throws SystemException {
651 return WebsiteLocalServiceUtil.getWebsites(
652 getCompanyId(), Contact.class.getName(), getContactId());
653 }
654
655 @Override
656 public boolean hasCompanyMx() throws PortalException, SystemException {
657 return hasCompanyMx(getEmailAddress());
658 }
659
660 @Override
661 public boolean hasCompanyMx(String emailAddress)
662 throws PortalException, SystemException {
663
664 if (Validator.isNull(emailAddress)) {
665 return false;
666 }
667
668 Company company = CompanyLocalServiceUtil.getCompanyById(
669 getCompanyId());
670
671 return company.hasCompanyMx(emailAddress);
672 }
673
674 @Override
675 public boolean hasMySites() throws PortalException, SystemException {
676 if (isDefaultUser()) {
677 return false;
678 }
679
680 int max = PropsValues.MY_SITES_MAX_ELEMENTS;
681
682 if (max == 1) {
683
684
685
686
687 max++;
688 }
689
690 List<Group> groups = getMySiteGroups(true, max);
691
692 return !groups.isEmpty();
693 }
694
695 @Override
696 public boolean hasOrganization() throws PortalException, SystemException {
697 List<Organization> organizations = getOrganizations();
698
699 return !organizations.isEmpty();
700 }
701
702 @Override
703 public boolean hasPrivateLayouts() throws PortalException, SystemException {
704 return LayoutLocalServiceUtil.hasLayouts(this, true);
705 }
706
707 @Override
708 public boolean hasPublicLayouts() throws PortalException, SystemException {
709 return LayoutLocalServiceUtil.hasLayouts(this, false);
710 }
711
712 @Override
713 public boolean hasReminderQuery() {
714 if (Validator.isNotNull(getReminderQueryQuestion()) &&
715 Validator.isNotNull(getReminderQueryAnswer())) {
716
717 return true;
718 }
719 else {
720 return false;
721 }
722 }
723
724 @Override
725 public boolean isActive() {
726 if (getStatus() == WorkflowConstants.STATUS_APPROVED) {
727 return true;
728 }
729 else {
730 return false;
731 }
732 }
733
734 @Override
735 public boolean isEmailAddressComplete() {
736 if (Validator.isNull(getEmailAddress()) ||
737 (PropsValues.USERS_EMAIL_ADDRESS_REQUIRED &&
738 Validator.isNull(getDisplayEmailAddress()))) {
739
740 return false;
741 }
742
743 return true;
744 }
745
746 @Override
747 public boolean isEmailAddressVerificationComplete() {
748 boolean emailAddressVerificationRequired = false;
749
750 try {
751 Company company = CompanyLocalServiceUtil.getCompany(
752 getCompanyId());
753
754 emailAddressVerificationRequired = company.isStrangersVerify();
755 }
756 catch (Exception e) {
757 _log.error(e, e);
758 }
759
760 if (emailAddressVerificationRequired) {
761 return super.isEmailAddressVerified();
762 }
763
764 return true;
765 }
766
767 @Override
768 public boolean isFemale() throws PortalException, SystemException {
769 return getFemale();
770 }
771
772 @Override
773 public boolean isMale() throws PortalException, SystemException {
774 return getMale();
775 }
776
777 @Override
778 public boolean isPasswordModified() {
779 return _passwordModified;
780 }
781
782 @Override
783 public boolean isReminderQueryComplete() {
784 if (PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
785 if (Validator.isNull(getReminderQueryQuestion()) ||
786 Validator.isNull(getReminderQueryAnswer())) {
787
788 return false;
789 }
790 }
791
792 return true;
793 }
794
795 @Override
796 public boolean isSetupComplete() {
797 if (isEmailAddressComplete() && isEmailAddressVerificationComplete() &&
798 !isPasswordReset() && isReminderQueryComplete() &&
799 isTermsOfUseComplete()) {
800
801 return true;
802 }
803
804 return false;
805 }
806
807 @Override
808 public boolean isTermsOfUseComplete() {
809 boolean termsOfUseRequired = false;
810
811 try {
812 termsOfUseRequired = PrefsPropsUtil.getBoolean(
813 getCompanyId(), PropsKeys.TERMS_OF_USE_REQUIRED);
814 }
815 catch (SystemException se) {
816 termsOfUseRequired = PropsValues.TERMS_OF_USE_REQUIRED;
817 }
818
819 if (termsOfUseRequired) {
820 return super.isAgreedToTermsOfUse();
821 }
822
823 return true;
824 }
825
826 @Override
827 public void setLanguageId(String languageId) {
828 _locale = LocaleUtil.fromLanguageId(languageId);
829
830 super.setLanguageId(LocaleUtil.toLanguageId(_locale));
831 }
832
833 @Override
834 public void setPasswordModified(boolean passwordModified) {
835 _passwordModified = passwordModified;
836 }
837
838 @Override
839 public void setPasswordUnencrypted(String passwordUnencrypted) {
840 _passwordUnencrypted = passwordUnencrypted;
841 }
842
843 @Override
844 public void setTimeZoneId(String timeZoneId) {
845 if (Validator.isNull(timeZoneId)) {
846 timeZoneId = TimeZoneUtil.getDefault().getID();
847 }
848
849 _timeZone = TimeZoneUtil.getTimeZone(timeZoneId);
850
851 super.setTimeZoneId(timeZoneId);
852 }
853
854 protected String getProfileFriendlyURL() {
855 if (Validator.isNull(PropsValues.USERS_PROFILE_FRIENDLY_URL)) {
856 return null;
857 }
858
859 return StringUtil.replace(
860 PropsValues.USERS_PROFILE_FRIENDLY_URL,
861 new String[] {"${liferay:screenName}", "${liferay:userId}"},
862 new String[] {
863 HtmlUtil.escapeURL(getScreenName()), String.valueOf(getUserId())
864 });
865 }
866
867 private static Log _log = LogFactoryUtil.getLog(UserImpl.class);
868
869 private Locale _locale;
870 private boolean _passwordModified;
871 private PasswordPolicy _passwordPolicy;
872 private String _passwordUnencrypted;
873 private transient Map<String, RemotePreference> _remotePreferences =
874 new HashMap<String, RemotePreference>();
875 private TimeZone _timeZone;
876
877 }