001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.ldap;
016    
017    import com.liferay.portal.NoSuchRoleException;
018    import com.liferay.portal.NoSuchUserException;
019    import com.liferay.portal.NoSuchUserGroupException;
020    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
021    import com.liferay.portal.kernel.cache.PortalCache;
022    import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
023    import com.liferay.portal.kernel.exception.PortalException;
024    import com.liferay.portal.kernel.exception.SystemException;
025    import com.liferay.portal.kernel.ldap.LDAPUtil;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.LocaleUtil;
031    import com.liferay.portal.kernel.util.PropsKeys;
032    import com.liferay.portal.kernel.util.SetUtil;
033    import com.liferay.portal.kernel.util.StringBundler;
034    import com.liferay.portal.kernel.util.StringPool;
035    import com.liferay.portal.kernel.util.StringUtil;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.model.Company;
038    import com.liferay.portal.model.CompanyConstants;
039    import com.liferay.portal.model.Contact;
040    import com.liferay.portal.model.Group;
041    import com.liferay.portal.model.Role;
042    import com.liferay.portal.model.RoleConstants;
043    import com.liferay.portal.model.User;
044    import com.liferay.portal.model.UserGroup;
045    import com.liferay.portal.security.auth.CompanyThreadLocal;
046    import com.liferay.portal.security.auth.ScreenNameGenerator;
047    import com.liferay.portal.security.auth.ScreenNameGeneratorFactory;
048    import com.liferay.portal.service.CompanyLocalServiceUtil;
049    import com.liferay.portal.service.GroupLocalServiceUtil;
050    import com.liferay.portal.service.LockLocalServiceUtil;
051    import com.liferay.portal.service.RoleLocalServiceUtil;
052    import com.liferay.portal.service.UserGroupLocalServiceUtil;
053    import com.liferay.portal.service.UserLocalServiceUtil;
054    import com.liferay.portal.util.PrefsPropsUtil;
055    import com.liferay.portal.util.PropsValues;
056    import com.liferay.portlet.expando.model.ExpandoBridge;
057    import com.liferay.portlet.expando.model.ExpandoTableConstants;
058    import com.liferay.portlet.expando.service.ExpandoValueLocalServiceUtil;
059    import com.liferay.portlet.expando.util.ExpandoConverterUtil;
060    
061    import java.io.Serializable;
062    
063    import java.text.ParseException;
064    
065    import java.util.ArrayList;
066    import java.util.Calendar;
067    import java.util.Date;
068    import java.util.HashMap;
069    import java.util.LinkedHashSet;
070    import java.util.List;
071    import java.util.Locale;
072    import java.util.Map;
073    import java.util.Properties;
074    import java.util.Set;
075    
076    import javax.naming.Binding;
077    import javax.naming.NameNotFoundException;
078    import javax.naming.NamingEnumeration;
079    import javax.naming.directory.Attribute;
080    import javax.naming.directory.Attributes;
081    import javax.naming.directory.SearchControls;
082    import javax.naming.directory.SearchResult;
083    import javax.naming.ldap.LdapContext;
084    
085    /**
086     * @author Michael C. Han
087     * @author Brian Wing Shun Chan
088     * @author Wesley Gong
089     * @author Hugo Huijser
090     */
091    public class PortalLDAPImporterImpl implements PortalLDAPImporter {
092    
093            public void importFromLDAP() throws Exception {
094                    List<Company> companies = CompanyLocalServiceUtil.getCompanies(false);
095    
096                    for (Company company : companies) {
097                            importFromLDAP(company.getCompanyId());
098                    }
099            }
100    
101            public void importFromLDAP(long companyId) throws Exception {
102                    if (!LDAPSettingsUtil.isImportEnabled(companyId)) {
103                            return;
104                    }
105    
106                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
107    
108                    if (LockLocalServiceUtil.hasLock(
109                                    defaultUserId, PortalLDAPImporterUtil.class.getName(),
110                                    companyId)) {
111    
112                            if (_log.isDebugEnabled()) {
113                                    _log.debug(
114                                            "Skipping LDAP import for company " + companyId +
115                                                    "because another LDAP import is in process");
116                            }
117    
118                            return;
119                    }
120    
121                    LockLocalServiceUtil.lock(
122                            defaultUserId, PortalLDAPImporterUtil.class.getName(), companyId,
123                            PortalLDAPImporterImpl.class.getName(), false,
124                            PropsValues.LDAP_IMPORT_LOCK_EXPIRATION_TIME);
125    
126                    long threadLocalCompanyId = CompanyThreadLocal.getCompanyId();
127    
128                    try {
129                            if (threadLocalCompanyId == CompanyConstants.SYSTEM) {
130                                    CompanyThreadLocal.setCompanyId(companyId);
131                            }
132    
133                            long[] ldapServerIds = StringUtil.split(
134                                    PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
135    
136                            for (long ldapServerId : ldapServerIds) {
137                                    importFromLDAP(ldapServerId, companyId);
138                            }
139    
140                            for (int ldapServerId = 0;; ldapServerId++) {
141                                    String postfix = LDAPSettingsUtil.getPropertyPostfix(
142                                            ldapServerId);
143    
144                                    String providerUrl = PrefsPropsUtil.getString(
145                                            companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
146    
147                                    if (Validator.isNull(providerUrl)) {
148                                            break;
149                                    }
150    
151                                    importFromLDAP(ldapServerId, companyId);
152                            }
153                    }
154                    finally {
155                            LockLocalServiceUtil.unlock(
156                                    PortalLDAPImporterUtil.class.getName(), companyId);
157    
158                            CompanyThreadLocal.setCompanyId(threadLocalCompanyId);
159                    }
160            }
161    
162            public void importFromLDAP(long ldapServerId, long companyId)
163                    throws Exception {
164    
165                    if (!LDAPSettingsUtil.isImportEnabled(companyId)) {
166                            return;
167                    }
168    
169                    LdapContext ldapContext = PortalLDAPUtil.getContext(
170                            ldapServerId, companyId);
171    
172                    if (ldapContext == null) {
173                            return;
174                    }
175    
176                    try {
177                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
178                                    ldapServerId, companyId);
179                            Properties userExpandoMappings =
180                                    LDAPSettingsUtil.getUserExpandoMappings(
181                                            ldapServerId, companyId);
182                            Properties contactMappings = LDAPSettingsUtil.getContactMappings(
183                                    ldapServerId, companyId);
184                            Properties contactExpandoMappings =
185                                    LDAPSettingsUtil.getContactExpandoMappings(
186                                            ldapServerId, companyId);
187                            Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
188                                    ldapServerId, companyId);
189    
190                            String importMethod = PrefsPropsUtil.getString(
191                                    companyId, PropsKeys.LDAP_IMPORT_METHOD);
192    
193                            if (importMethod.equals(_IMPORT_BY_GROUP)) {
194                                    importFromLDAPByGroup(
195                                            ldapServerId, companyId, ldapContext, userMappings,
196                                            userExpandoMappings, contactMappings,
197                                            contactExpandoMappings, groupMappings);
198                            }
199                            else if (importMethod.equals(_IMPORT_BY_USER)) {
200                                    importFromLDAPByUser(
201                                            ldapServerId, companyId, ldapContext, userMappings,
202                                            userExpandoMappings, contactMappings,
203                                            contactExpandoMappings, groupMappings);
204                            }
205                    }
206                    catch (Exception e) {
207                            _log.error("Error importing LDAP users and groups", e);
208                    }
209                    finally {
210                            if (ldapContext != null) {
211                                    ldapContext.close();
212                            }
213                    }
214            }
215    
216            public User importLDAPUser(
217                            long ldapServerId, long companyId, LdapContext ldapContext,
218                            Attributes attributes, String password)
219                    throws Exception {
220    
221                    Properties userMappings = LDAPSettingsUtil.getUserMappings(
222                            ldapServerId, companyId);
223                    Properties userExpandoMappings =
224                            LDAPSettingsUtil.getUserExpandoMappings(ldapServerId, companyId);
225                    Properties contactMappings = LDAPSettingsUtil.getContactMappings(
226                            ldapServerId, companyId);
227                    Properties contactExpandoMappings =
228                            LDAPSettingsUtil.getContactExpandoMappings(ldapServerId, companyId);
229    
230                    User user = importUser(
231                            companyId, attributes, userMappings, userExpandoMappings,
232                            contactMappings, contactExpandoMappings, password);
233    
234                    Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
235                            ldapServerId, companyId);
236    
237                    importGroups(
238                            ldapServerId, companyId, ldapContext, attributes, user,
239                            userMappings, groupMappings);
240    
241                    return user;
242            }
243    
244            public User importLDAPUser(
245                            long ldapServerId, long companyId, String emailAddress,
246                            String screenName)
247                    throws Exception {
248    
249                    LdapContext ldapContext = null;
250    
251                    NamingEnumeration<SearchResult> enu = null;
252    
253                    try {
254                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
255    
256                            String baseDN = PrefsPropsUtil.getString(
257                                    companyId, PropsKeys.LDAP_BASE_DN + postfix);
258    
259                            ldapContext = PortalLDAPUtil.getContext(ldapServerId, companyId);
260    
261                            if (ldapContext == null) {
262                                    throw new SystemException("Failed to bind to the LDAP server");
263                            }
264    
265                            String filter = PrefsPropsUtil.getString(
266                                    companyId, PropsKeys.LDAP_AUTH_SEARCH_FILTER + postfix);
267    
268                            if (_log.isDebugEnabled()) {
269                                    _log.debug("Search filter before transformation " + filter);
270                            }
271    
272                            filter = StringUtil.replace(
273                                    filter,
274                                    new String[] {
275                                            "@company_id@", "@email_address@", "@screen_name@"
276                                    },
277                                    new String[] {
278                                            String.valueOf(companyId), emailAddress, screenName
279                                    });
280    
281                            LDAPUtil.validateFilter(filter);
282    
283                            if (_log.isDebugEnabled()) {
284                                    _log.debug("Search filter after transformation " + filter);
285                            }
286    
287                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
288                                    ldapServerId, companyId);
289    
290                            String userMappingsScreenName = GetterUtil.getString(
291                                    userMappings.getProperty("screenName")).toLowerCase();
292    
293                            SearchControls searchControls = new SearchControls(
294                                    SearchControls.SUBTREE_SCOPE, 1, 0,
295                                    new String[] {userMappingsScreenName}, false, false);
296    
297                            enu = ldapContext.search(baseDN, filter, searchControls);
298    
299                            if (enu.hasMoreElements()) {
300                                    if (_log.isDebugEnabled()) {
301                                            _log.debug("Search filter returned at least one result");
302                                    }
303    
304                                    Binding binding = enu.nextElement();
305    
306                                    Attributes attributes = PortalLDAPUtil.getUserAttributes(
307                                            ldapServerId, companyId, ldapContext,
308                                            PortalLDAPUtil.getNameInNamespace(
309                                                    ldapServerId, companyId, binding));
310    
311                                    return importLDAPUser(
312                                            ldapServerId, companyId, ldapContext, attributes,
313                                            StringPool.BLANK);
314                            }
315                            else {
316                                    return null;
317                            }
318                    }
319                    catch (Exception e) {
320                            if (_log.isWarnEnabled()) {
321                                    _log.warn("Problem accessing LDAP server " + e.getMessage());
322                            }
323    
324                            if (_log.isDebugEnabled()) {
325                                    _log.debug(e, e);
326                            }
327    
328                            throw new SystemException(
329                                    "Problem accessing LDAP server " + e.getMessage());
330                    }
331                    finally {
332                            if (enu != null) {
333                                    enu.close();
334                            }
335    
336                            if (ldapContext != null) {
337                                    ldapContext.close();
338                            }
339                    }
340            }
341    
342            public User importLDAPUser(
343                            long companyId, String emailAddress, String screenName)
344                    throws Exception {
345    
346                    long[] ldapServerIds = StringUtil.split(
347                            PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
348    
349                    for (long ldapServerId : ldapServerIds) {
350                            User user = importLDAPUser(
351                                    ldapServerId, companyId, emailAddress, screenName);
352    
353                            if (user != null) {
354                                    return user;
355                            }
356                    }
357    
358                    for (int ldapServerId = 0;; ldapServerId++) {
359                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
360    
361                            String providerUrl = PrefsPropsUtil.getString(
362                                    companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
363    
364                            if (Validator.isNull(providerUrl)) {
365                                    break;
366                            }
367    
368                            User user = importLDAPUser(
369                                    ldapServerId, companyId, emailAddress, screenName);
370    
371                            if (user != null) {
372                                    return user;
373                            }
374                    }
375    
376                    if (_log.isDebugEnabled()) {
377                            if (Validator.isNotNull(emailAddress)) {
378                                    _log.debug(
379                                            "User with the email address " + emailAddress +
380                                    " was not found in any LDAP servers");
381                            }
382                            else {
383                                    _log.debug(
384                                            "User with the screen name " + screenName +
385                                    " was not found in any LDAP servers");
386                            }
387                    }
388    
389                    return null;
390            }
391    
392            public User importLDAPUserByScreenName(long companyId, String screenName)
393                    throws Exception {
394    
395                    long ldapServerId = PortalLDAPUtil.getLdapServerId(
396                            companyId, screenName, StringPool.BLANK);
397    
398                    SearchResult result = (SearchResult)PortalLDAPUtil.getUser(
399                            ldapServerId, companyId, screenName, StringPool.BLANK);
400    
401                    if (result == null) {
402                            if (_log.isWarnEnabled()) {
403                                    _log.warn(
404                                            "No user was found in LDAP with screenName " + screenName);
405                            }
406    
407                            return null;
408                    }
409    
410                    LdapContext ldapContext = PortalLDAPUtil.getContext(
411                            ldapServerId, companyId);
412    
413                    String fullUserDN = PortalLDAPUtil.getNameInNamespace(
414                            ldapServerId, companyId, result);
415    
416                    Attributes attributes = PortalLDAPUtil.getUserAttributes(
417                            ldapServerId, companyId, ldapContext, fullUserDN);
418    
419                    User user = importLDAPUser(
420                            ldapServerId, companyId, ldapContext, attributes, StringPool.BLANK);
421    
422                    ldapContext.close();
423    
424                    return user;
425            }
426    
427            public void setLDAPToPortalConverter(
428                    LDAPToPortalConverter ldapToPortalConverter) {
429    
430                    _ldapToPortalConverter = ldapToPortalConverter;
431            }
432    
433            protected void addRole(
434                            long companyId, LDAPGroup ldapGroup, UserGroup userGroup)
435                    throws Exception {
436    
437                    if (!PropsValues.LDAP_IMPORT_CREATE_ROLE_PER_GROUP) {
438                            return;
439                    }
440    
441                    Role role = null;
442    
443                    try {
444                            role = RoleLocalServiceUtil.getRole(
445                                    companyId, ldapGroup.getGroupName());
446                    }
447                    catch (NoSuchRoleException nsre) {
448                            User defaultUser = UserLocalServiceUtil.getDefaultUser(companyId);
449    
450                            Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
451    
452                            descriptionMap.put(
453                                    LocaleUtil.getDefault(), "Autogenerated role from LDAP import");
454    
455                            role = RoleLocalServiceUtil.addRole(
456                                    defaultUser.getUserId(), null, 0, ldapGroup.getGroupName(),
457                                    null, descriptionMap, RoleConstants.TYPE_REGULAR, null);
458                    }
459    
460                    Group group = userGroup.getGroup();
461    
462                    if (GroupLocalServiceUtil.hasRoleGroup(
463                                    role.getRoleId(), group.getGroupId())) {
464    
465                            return;
466                    }
467    
468                    GroupLocalServiceUtil.addRoleGroups(
469                            role.getRoleId(), new long[] {group.getGroupId()});
470            }
471    
472            protected User addUser(long companyId, LDAPUser ldapUser, String password)
473                    throws Exception {
474    
475                    if (_log.isDebugEnabled()) {
476                            _log.debug("Adding user " + ldapUser.getEmailAddress());
477                    }
478    
479                    boolean autoPassword = ldapUser.isAutoPassword();
480    
481                    if (!PropsValues.LDAP_IMPORT_USER_PASSWORD_ENABLED) {
482                            autoPassword =
483                                    PropsValues.LDAP_IMPORT_USER_PASSWORD_AUTOGENERATED &&
484                                    !PropsValues.AUTH_PIPELINE_ENABLE_LIFERAY_CHECK;
485    
486                            if (!autoPassword) {
487                                    String defaultPassword =
488                                            PropsValues.LDAP_IMPORT_USER_PASSWORD_DEFAULT;
489    
490                                    if (defaultPassword.equalsIgnoreCase(
491                                                    _USER_PASSWORD_SCREEN_NAME)) {
492    
493                                            defaultPassword = ldapUser.getScreenName();
494                                    }
495    
496                                    password = defaultPassword;
497                            }
498                    }
499    
500                    Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
501    
502                    birthdayCal.setTime(ldapUser.getBirthday());
503    
504                    int birthdayMonth = birthdayCal.get(Calendar.MONTH);
505                    int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
506                    int birthdayYear = birthdayCal.get(Calendar.YEAR);
507    
508                    User user = UserLocalServiceUtil.addUser(
509                            ldapUser.getCreatorUserId(), companyId, autoPassword, password,
510                            password, ldapUser.isAutoScreenName(), ldapUser.getScreenName(),
511                            ldapUser.getEmailAddress(), 0, StringPool.BLANK,
512                            ldapUser.getLocale(), ldapUser.getFirstName(),
513                            ldapUser.getMiddleName(), ldapUser.getLastName(), 0, 0,
514                            ldapUser.isMale(), birthdayMonth, birthdayDay, birthdayYear,
515                            StringPool.BLANK, ldapUser.getGroupIds(),
516                            ldapUser.getOrganizationIds(), ldapUser.getRoleIds(),
517                            ldapUser.getUserGroupIds(), ldapUser.isSendEmail(),
518                            ldapUser.getServiceContext());
519    
520                    if (ldapUser.isUpdatePortrait()) {
521                            byte[] portraitBytes = ldapUser.getPortraitBytes();
522    
523                            if ((portraitBytes != null) && (portraitBytes.length > 0)) {
524                                    user = UserLocalServiceUtil.updatePortrait(
525                                            user.getUserId(), portraitBytes);
526                            }
527                    }
528    
529                    return user;
530            }
531    
532            protected void addUserGroupsNotAddedByLDAPImport(
533                            long userId, Set<Long> userGroupIds)
534                    throws Exception {
535    
536                    List<UserGroup> userGroups =
537                            UserGroupLocalServiceUtil.getUserUserGroups(userId);
538    
539                    for (UserGroup userGroup : userGroups) {
540                            if (!userGroup.isAddedByLDAPImport()) {
541                                    userGroupIds.add(userGroup.getUserGroupId());
542                            }
543                    }
544            }
545    
546            protected String escapeValue(String value) {
547                    return StringUtil.replace(value, "\\,", "\\\\,");
548            }
549    
550            protected User getUser(long companyId, LDAPUser ldapUser) throws Exception {
551                    User user = null;
552    
553                    try {
554                            String authType = PrefsPropsUtil.getString(
555                                    companyId, PropsKeys.COMPANY_SECURITY_AUTH_TYPE,
556                                    PropsValues.COMPANY_SECURITY_AUTH_TYPE);
557    
558                            if (authType.equals(CompanyConstants.AUTH_TYPE_SN) &&
559                                    !ldapUser.isAutoScreenName()) {
560    
561                                    user = UserLocalServiceUtil.getUserByScreenName(
562                                            companyId, ldapUser.getScreenName());
563                            }
564                            else {
565                                    user = UserLocalServiceUtil.getUserByEmailAddress(
566                                            companyId, ldapUser.getEmailAddress());
567                            }
568                    }
569                    catch (NoSuchUserException nsue) {
570                    }
571    
572                    return user;
573            }
574    
575            protected Attribute getUsers(
576                            long ldapServerId, long companyId, LdapContext ldapContext,
577                            Attributes attributes, UserGroup userGroup,
578                            Properties groupMappings)
579                    throws Exception {
580    
581                    Attribute attribute = attributes.get(groupMappings.getProperty("user"));
582    
583                    if (attribute == null) {
584                            return null;
585                    }
586    
587                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
588    
589                    String baseDN = PrefsPropsUtil.getString(
590                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
591    
592                    StringBundler sb = new StringBundler(7);
593    
594                    sb.append("(&");
595                    sb.append(
596                            PrefsPropsUtil.getString(
597                                    companyId,
598                                    PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix));
599                    sb.append("(");
600                    sb.append(groupMappings.getProperty("groupName"));
601                    sb.append("=");
602                    sb.append(escapeValue(userGroup.getName()));
603                    sb.append("))");
604    
605                    return PortalLDAPUtil.getMultivaluedAttribute(
606                            companyId, ldapContext, baseDN, sb.toString(), attribute);
607            }
608    
609            protected void importFromLDAPByGroup(
610                            long ldapServerId, long companyId, LdapContext ldapContext,
611                            Properties userMappings, Properties userExpandoMappings,
612                            Properties contactMappings, Properties contactExpandoMappings,
613                            Properties groupMappings)
614                    throws Exception {
615    
616                    byte[] cookie = new byte[0];
617    
618                    while (cookie != null) {
619                            List<SearchResult> searchResults = new ArrayList<SearchResult>();
620    
621                            String groupMappingsGroupName = GetterUtil.getString(
622                                    groupMappings.getProperty("groupName")).toLowerCase();
623    
624                            cookie = PortalLDAPUtil.getGroups(
625                                    ldapServerId, companyId, ldapContext, cookie, 0,
626                                    new String[] {groupMappingsGroupName}, searchResults);
627    
628                            for (SearchResult searchResult : searchResults) {
629                                    try {
630                                            Attributes attributes = PortalLDAPUtil.getGroupAttributes(
631                                                    ldapServerId, companyId, ldapContext,
632                                                    PortalLDAPUtil.getNameInNamespace(
633                                                            ldapServerId, companyId, searchResult),
634                                                    true);
635    
636                                            UserGroup userGroup = importUserGroup(
637                                                    companyId, attributes, groupMappings);
638    
639                                            Attribute usersAttribute = getUsers(
640                                                    ldapServerId, companyId, ldapContext, attributes,
641                                                    userGroup, groupMappings);
642    
643                                            if (usersAttribute == null) {
644                                                    if (_log.isInfoEnabled()) {
645                                                            _log.info(
646                                                                    "No users found in " + userGroup.getName());
647                                                    }
648    
649                                                    continue;
650                                            }
651    
652                                            importUsers(
653                                                    ldapServerId, companyId, ldapContext, userMappings,
654                                                    userExpandoMappings, contactMappings,
655                                                    contactExpandoMappings, userGroup.getUserGroupId(),
656                                                    usersAttribute);
657                                    }
658                                    catch (Exception e) {
659                                            _log.error("Unable to import group " + searchResult, e);
660                                    }
661                            }
662                    }
663            }
664    
665            protected void importFromLDAPByUser(
666                            long ldapServerId, long companyId, LdapContext ldapContext,
667                            Properties userMappings, Properties userExpandoMappings,
668                            Properties contactMappings, Properties contactExpandoMappings,
669                            Properties groupMappings)
670                    throws Exception {
671    
672                    byte[] cookie = new byte[0];
673    
674                    while (cookie != null) {
675                            List<SearchResult> searchResults = new ArrayList<SearchResult>();
676    
677                            String userMappingsScreenName = GetterUtil.getString(
678                                    userMappings.getProperty("screenName")).toLowerCase();
679    
680                            cookie = PortalLDAPUtil.getUsers(
681                                    ldapServerId, companyId, ldapContext, cookie, 0,
682                                    new String[] {userMappingsScreenName}, searchResults);
683    
684                            for (SearchResult searchResult : searchResults) {
685                                    try {
686                                            Attributes userAttributes =
687                                                    PortalLDAPUtil.getUserAttributes(
688                                                            ldapServerId, companyId, ldapContext,
689                                                            PortalLDAPUtil.getNameInNamespace(
690                                                                    ldapServerId, companyId, searchResult));
691    
692                                            User user = importUser(
693                                                    companyId, userAttributes, userMappings,
694                                                    userExpandoMappings, contactMappings,
695                                                    contactExpandoMappings, StringPool.BLANK);
696    
697                                            importGroups(
698                                                    ldapServerId, companyId, ldapContext, userAttributes,
699                                                    user, userMappings, groupMappings);
700                                    }
701                                    catch (Exception e) {
702                                            _log.error("Unable to import user " + searchResult, e);
703                                    }
704                            }
705                    }
706            }
707    
708            protected Set<Long> importGroup(
709                            long ldapServerId, long companyId, LdapContext ldapContext,
710                            String fullGroupDN, User user, Properties groupMappings,
711                            Set<Long> newUserGroupIds)
712                    throws Exception {
713    
714                    String userGroupIdKey = null;
715    
716                    Long userGroupId = null;
717    
718                    if (PropsValues.LDAP_IMPORT_GROUP_CACHE_ENABLED) {
719                            StringBundler sb = new StringBundler(5);
720    
721                            sb.append(ldapServerId);
722                            sb.append(StringPool.UNDERLINE);
723                            sb.append(companyId);
724                            sb.append(StringPool.UNDERLINE);
725                            sb.append(fullGroupDN);
726    
727                            userGroupIdKey = sb.toString();
728    
729                            userGroupId = _portalCache.get(userGroupIdKey);
730                    }
731    
732                    if (userGroupId != null) {
733                            if (_log.isDebugEnabled()) {
734                                    _log.debug("Skipping reimport of full group DN " + fullGroupDN);
735                            }
736                    }
737                    else {
738                            if (_log.isDebugEnabled()) {
739                                    _log.debug("Importing full group DN " + fullGroupDN);
740                            }
741    
742                            Attributes groupAttributes = null;
743    
744                            try {
745                                    groupAttributes = PortalLDAPUtil.getGroupAttributes(
746                                            ldapServerId, companyId, ldapContext, fullGroupDN);
747                            }
748                            catch (NameNotFoundException nnfe) {
749                                    _log.error(
750                                            "LDAP group not found with full group DN " + fullGroupDN,
751                                            nnfe);
752                            }
753    
754                            UserGroup userGroup = importUserGroup(
755                                    companyId, groupAttributes, groupMappings);
756    
757                            userGroupId = userGroup.getUserGroupId();
758    
759                            if (PropsValues.LDAP_IMPORT_GROUP_CACHE_ENABLED) {
760                                    _portalCache.put(userGroupIdKey, userGroupId);
761                            }
762                    }
763    
764                    if (userGroupId != null) {
765                            if (_log.isDebugEnabled()) {
766                                    _log.debug(
767                                            "Adding " + user.getUserId() + " to group " + userGroupId);
768                            }
769    
770                            newUserGroupIds.add(userGroupId);
771                    }
772    
773                    return newUserGroupIds;
774            }
775    
776            protected void importGroups(
777                            long ldapServerId, long companyId, LdapContext ldapContext,
778                            Attributes attributes, User user, Properties userMappings,
779                            Properties groupMappings)
780                    throws Exception {
781    
782                    Set<Long> newUserGroupIds = new LinkedHashSet<Long>();
783    
784                    if (PrefsPropsUtil.getBoolean(
785                                    companyId, PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER_ENABLED)) {
786    
787                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
788    
789                            String baseDN = PrefsPropsUtil.getString(
790                                    companyId, PropsKeys.LDAP_BASE_DN + postfix);
791    
792                            Binding binding = PortalLDAPUtil.getUser(
793                                    ldapServerId, companyId, user.getScreenName(),
794                                    user.getEmailAddress());
795    
796                            String fullUserDN = PortalLDAPUtil.getNameInNamespace(
797                                    ldapServerId, companyId, binding);
798    
799                            StringBundler sb = new StringBundler(9);
800    
801                            sb.append(StringPool.OPEN_PARENTHESIS);
802                            sb.append(StringPool.AMPERSAND);
803                            sb.append(
804                                    PrefsPropsUtil.getString(
805                                            companyId,
806                                            PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix));
807                            sb.append(StringPool.OPEN_PARENTHESIS);
808                            sb.append(groupMappings.getProperty("user"));
809                            sb.append(StringPool.EQUAL);
810                            sb.append(escapeValue(fullUserDN));
811                            sb.append(StringPool.CLOSE_PARENTHESIS);
812                            sb.append(StringPool.CLOSE_PARENTHESIS);
813    
814                            byte[] cookie = new byte[0];
815    
816                            while (cookie != null) {
817                                    List<SearchResult> searchResults =
818                                            new ArrayList<SearchResult>();
819    
820                                    String groupMappingsGroupName = GetterUtil.getString(
821                                            groupMappings.getProperty("groupName")).toLowerCase();
822    
823                                    cookie = PortalLDAPUtil.searchLDAP(
824                                            companyId, ldapContext, cookie, 0, baseDN, sb.toString(),
825                                            new String[] {groupMappingsGroupName}, searchResults);
826    
827                                    for (SearchResult searchResult : searchResults) {
828                                            String fullGroupDN = PortalLDAPUtil.getNameInNamespace(
829                                                    ldapServerId, companyId, searchResult);
830    
831                                            newUserGroupIds = importGroup(
832                                                    ldapServerId, companyId, ldapContext, fullGroupDN, user,
833                                                    groupMappings, newUserGroupIds);
834                                    }
835                            }
836                    }
837                    else {
838                            String userMappingsGroup = userMappings.getProperty("group");
839    
840                            if (Validator.isNull(userMappingsGroup)) {
841                                    return;
842                            }
843    
844                            Attribute userGroupAttribute = attributes.get(userMappingsGroup);
845    
846                            if (userGroupAttribute == null) {
847                                    return;
848                            }
849    
850                            for (int i = 0; i < userGroupAttribute.size(); i++) {
851                                    String fullGroupDN = (String)userGroupAttribute.get(i);
852    
853                                    newUserGroupIds = importGroup(
854                                            ldapServerId, companyId, ldapContext, fullGroupDN, user,
855                                            groupMappings, newUserGroupIds);
856                            }
857                    }
858    
859                    addUserGroupsNotAddedByLDAPImport(user.getUserId(), newUserGroupIds);
860    
861                    for (long newUserGroupId : newUserGroupIds) {
862                            UserLocalServiceUtil.addUserGroupUsers(
863                                    newUserGroupId, new long[] {user.getUserId()});
864                    }
865    
866                    List<UserGroup> userUserGroups =
867                            UserGroupLocalServiceUtil.getUserUserGroups(user.getUserId());
868    
869                    for (UserGroup userGroup : userUserGroups) {
870                            if (!newUserGroupIds.contains(userGroup.getUserGroupId())) {
871                                    UserLocalServiceUtil.deleteUserGroupUser(
872                                            userGroup.getUserGroupId(), user.getUserId());
873                            }
874                    }
875            }
876    
877            protected User importUser(
878                            long companyId, Attributes attributes, Properties userMappings,
879                            Properties userExpandoMappings, Properties contactMappings,
880                            Properties contactExpandoMappings, String password)
881                    throws Exception {
882    
883                    LDAPUserTransactionThreadLocal.setOriginatesFromLDAP(true);
884    
885                    try {
886                            AttributesTransformer attributesTransformer =
887                                    AttributesTransformerFactory.getInstance();
888    
889                            attributes = attributesTransformer.transformUser(attributes);
890    
891                            LDAPUser ldapUser = _ldapToPortalConverter.importLDAPUser(
892                                    companyId, attributes, userMappings, userExpandoMappings,
893                                    contactMappings, contactExpandoMappings, password);
894    
895                            User user = getUser(companyId, ldapUser);
896    
897                            if ((user != null) && user.isDefaultUser()) {
898                                    return user;
899                            }
900    
901                            if (user == null) {
902                                    user = addUser(companyId, ldapUser, password);
903                            }
904    
905                            String modifiedDate = LDAPUtil.getAttributeString(
906                                    attributes, "modifyTimestamp");
907    
908                            user = updateUser(
909                                    companyId, ldapUser, user, password, modifiedDate);
910    
911                            updateExpandoAttributes(user, ldapUser);
912    
913                            return user;
914                    }
915                    finally {
916                            LDAPUserTransactionThreadLocal.setOriginatesFromLDAP(false);
917                    }
918            }
919    
920            protected UserGroup importUserGroup(
921                            long companyId, Attributes attributes, Properties groupMappings)
922                    throws Exception {
923    
924                    AttributesTransformer attributesTransformer =
925                            AttributesTransformerFactory.getInstance();
926    
927                    attributes = attributesTransformer.transformGroup(attributes);
928    
929                    LDAPGroup ldapGroup = _ldapToPortalConverter.importLDAPGroup(
930                            companyId, attributes, groupMappings);
931    
932                    UserGroup userGroup = null;
933    
934                    try {
935                            userGroup = UserGroupLocalServiceUtil.getUserGroup(
936                                    companyId, ldapGroup.getGroupName());
937    
938                            UserGroupLocalServiceUtil.updateUserGroup(
939                                    companyId, userGroup.getUserGroupId(), ldapGroup.getGroupName(),
940                                    ldapGroup.getDescription());
941                    }
942                    catch (NoSuchUserGroupException nsuge) {
943                            if (_log.isDebugEnabled()) {
944                                    _log.debug(
945                                            "Adding user group to portal " + ldapGroup.getGroupName());
946                            }
947    
948                            long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
949                                    companyId);
950    
951                            LDAPUserGroupTransactionThreadLocal.setOriginatesFromLDAP(true);
952    
953                            try {
954                                    userGroup = UserGroupLocalServiceUtil.addUserGroup(
955                                            defaultUserId, companyId, ldapGroup.getGroupName(),
956                                            ldapGroup.getDescription());
957                            }
958                            catch (Exception e) {
959                                    if (_log.isWarnEnabled()) {
960                                            _log.warn(
961                                                    "Unable to create user group " +
962                                                            ldapGroup.getGroupName());
963                                    }
964    
965                                    if (_log.isDebugEnabled()) {
966                                            _log.debug(e, e);
967                                    }
968                            }
969                            finally {
970                                    LDAPUserGroupTransactionThreadLocal.setOriginatesFromLDAP(
971                                            false);
972                            }
973                    }
974    
975                    addRole(companyId, ldapGroup, userGroup);
976    
977                    return userGroup;
978            }
979    
980            protected void importUsers(
981                            long ldapServerId, long companyId, LdapContext ldapContext,
982                            Properties userMappings, Properties userExpandoMappings,
983                            Properties contactMappings, Properties contactExpandoMappings,
984                            long userGroupId, Attribute attribute)
985                    throws Exception {
986    
987                    Set<Long> newUserIds = new LinkedHashSet<Long>(attribute.size());
988    
989                    for (int i = 0; i < attribute.size(); i++) {
990                            String fullUserDN = (String)attribute.get(i);
991    
992                            Attributes userAttributes = null;
993    
994                            try {
995                                    userAttributes = PortalLDAPUtil.getUserAttributes(
996                                            ldapServerId, companyId, ldapContext, fullUserDN);
997                            }
998                            catch (NameNotFoundException nnfe) {
999                                    _log.error(
1000                                            "LDAP user not found with fullUserDN " + fullUserDN, nnfe);
1001    
1002                                    continue;
1003                            }
1004    
1005                            try {
1006                                    User user = importUser(
1007                                            companyId, userAttributes, userMappings,
1008                                            userExpandoMappings, contactMappings,
1009                                            contactExpandoMappings, StringPool.BLANK);
1010    
1011                                    if (user != null) {
1012                                            if (_log.isDebugEnabled()) {
1013                                                    _log.debug(
1014                                                            "Adding " + user.getUserId() + " to group " +
1015                                                                    userGroupId);
1016                                            }
1017    
1018                                            UserLocalServiceUtil.addUserGroupUsers(
1019                                                    userGroupId, new long[] {user.getUserId()});
1020    
1021                                            newUserIds.add(user.getUserId());
1022                                    }
1023                            }
1024                            catch (Exception e) {
1025                                    _log.error("Unable to load user " + userAttributes, e);
1026                            }
1027                    }
1028    
1029                    List<User> userGroupUsers = UserLocalServiceUtil.getUserGroupUsers(
1030                            userGroupId);
1031    
1032                    for (User user : userGroupUsers) {
1033                            if (!newUserIds.contains(user.getUserId())) {
1034                                    UserLocalServiceUtil.deleteUserGroupUser(
1035                                            userGroupId, user.getUserId());
1036                            }
1037                    }
1038            }
1039    
1040            protected void populateExpandoAttributes(
1041                    ExpandoBridge expandoBridge, Map<String, String[]> expandoAttributes) {
1042    
1043                    if (expandoAttributes.isEmpty()) {
1044                            return;
1045                    }
1046    
1047                    Map<String, Serializable> serializedExpandoAttributes =
1048                            new HashMap<String, Serializable>();
1049    
1050                    for (Map.Entry<String, String[]> expandoAttribute :
1051                                    expandoAttributes.entrySet()) {
1052    
1053                            String name = expandoAttribute.getKey();
1054    
1055                            if (!expandoBridge.hasAttribute(name)) {
1056                                    continue;
1057                            }
1058    
1059                            int type = expandoBridge.getAttributeType(name);
1060    
1061                            Serializable value =
1062                                    ExpandoConverterUtil.getAttributeFromStringArray(
1063                                            type, expandoAttribute.getValue());
1064    
1065                            serializedExpandoAttributes.put(name, value);
1066                    }
1067    
1068                    try {
1069                            ExpandoValueLocalServiceUtil.addValues(
1070                                    expandoBridge.getCompanyId(), expandoBridge.getClassName(),
1071                                    ExpandoTableConstants.DEFAULT_TABLE_NAME,
1072                                    expandoBridge.getClassPK(), serializedExpandoAttributes);
1073                    }
1074                    catch (Exception e) {
1075                            if (_log.isWarnEnabled()) {
1076                                    _log.warn("Unable to populate expando attributes");
1077                            }
1078    
1079                            if (_log.isDebugEnabled()) {
1080                                    _log.debug(e, e);
1081                            }
1082                    }
1083            }
1084    
1085            protected void setProperty(
1086                    Object bean1, Object bean2, String propertyName) {
1087    
1088                    Object value = BeanPropertiesUtil.getObject(bean1, propertyName);
1089                    Object defaultValue = BeanPropertiesUtil.getObject(bean2, propertyName);
1090    
1091                    if ((value == null) || value.equals(StringPool.BLANK)) {
1092                            BeanPropertiesUtil.setProperty(bean1, propertyName, defaultValue);
1093                    }
1094            }
1095    
1096            protected void updateExpandoAttributes(User user, LDAPUser ldapUser)
1097                    throws Exception {
1098    
1099                    ExpandoBridge userExpandoBridge = user.getExpandoBridge();
1100    
1101                    populateExpandoAttributes(
1102                            userExpandoBridge, ldapUser.getUserExpandoAttributes());
1103    
1104                    Contact contact = user.getContact();
1105    
1106                    ExpandoBridge contactExpandoBridge = contact.getExpandoBridge();
1107    
1108                    populateExpandoAttributes(
1109                            contactExpandoBridge, ldapUser.getContactExpandoAttributes());
1110            }
1111    
1112            protected void updateLDAPUser(User ldapUser, Contact ldapContact, User user)
1113                    throws PortalException, SystemException {
1114    
1115                    Contact contact = user.getContact();
1116    
1117                    for (String propertyName : _CONTACT_PROPERTY_NAMES) {
1118                            setProperty(ldapContact, contact, propertyName);
1119                    }
1120    
1121                    for (String propertyName : _USER_PROPERTY_NAMES) {
1122                            setProperty(ldapUser, user, propertyName);
1123                    }
1124            }
1125    
1126            protected User updateUser(
1127                            long companyId, LDAPUser ldapUser, User user, String password,
1128                            String modifiedDate)
1129                    throws Exception {
1130    
1131                    Date ldapUserModifiedDate = null;
1132    
1133                    try {
1134                            if (Validator.isNull(modifiedDate)) {
1135                                    if (_log.isInfoEnabled()) {
1136                                            _log.info(
1137                                                    "LDAP entry never modified, skipping user " +
1138                                                            user.getEmailAddress());
1139                                    }
1140    
1141                                    return user;
1142                            }
1143                            else {
1144                                    ldapUserModifiedDate = LDAPUtil.parseDate(modifiedDate);
1145                            }
1146    
1147                            if (ldapUserModifiedDate.equals(user.getModifiedDate()) &&
1148                                    ldapUser.isAutoPassword()) {
1149    
1150                                    if (_log.isDebugEnabled()) {
1151                                            _log.debug(
1152                                                    "User is already synchronized, skipping user " +
1153                                                            user.getEmailAddress());
1154                                    }
1155    
1156                                    return user;
1157                            }
1158                    }
1159                    catch (ParseException pe) {
1160                            if (_log.isDebugEnabled()) {
1161                                    _log.debug(
1162                                            "Unable to parse LDAP modify timestamp " + modifiedDate,
1163                                            pe);
1164                            }
1165                    }
1166    
1167                    boolean passwordReset = ldapUser.isPasswordReset();
1168    
1169                    if (PrefsPropsUtil.getBoolean(
1170                                    companyId, PropsKeys.LDAP_EXPORT_ENABLED,
1171                                    PropsValues.LDAP_EXPORT_ENABLED)) {
1172    
1173                            passwordReset = user.isPasswordReset();
1174                    }
1175    
1176                    if (!PropsValues.LDAP_IMPORT_USER_PASSWORD_ENABLED) {
1177                            password = PropsValues.LDAP_IMPORT_USER_PASSWORD_DEFAULT;
1178    
1179                            if (password.equalsIgnoreCase(_USER_PASSWORD_SCREEN_NAME)) {
1180                                    password = ldapUser.getScreenName();
1181                            }
1182                    }
1183    
1184                    if (Validator.isNull(ldapUser.getScreenName())) {
1185                            ldapUser.setAutoScreenName(true);
1186                    }
1187    
1188                    if (ldapUser.isAutoScreenName()) {
1189                            ScreenNameGenerator screenNameGenerator =
1190                                    ScreenNameGeneratorFactory.getInstance();
1191    
1192                            ldapUser.setScreenName(
1193                                    screenNameGenerator.generate(
1194                                            companyId, user.getUserId(), ldapUser.getEmailAddress()));
1195                    }
1196    
1197                    Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
1198    
1199                    birthdayCal.setTime(user.getContact().getBirthday());
1200    
1201                    int birthdayMonth = birthdayCal.get(Calendar.MONTH);
1202                    int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
1203                    int birthdayYear = birthdayCal.get(Calendar.YEAR);
1204    
1205                    if (ldapUser.isUpdatePassword()) {
1206                            UserLocalServiceUtil.updatePassword(
1207                                    user.getUserId(), password, password, passwordReset, true);
1208                    }
1209    
1210                    Contact contact = user.getContact();
1211    
1212                    Set<String> ldapIgnoreAttributes = SetUtil.fromArray(
1213                            PropsValues.LDAP_USER_IGNORE_ATTRIBUTES);
1214    
1215                    for (String attribute : ldapIgnoreAttributes) {
1216                            Object value = BeanPropertiesUtil.getObjectSilent(user, attribute);
1217    
1218                            if (value == null) {
1219                                    value = BeanPropertiesUtil.getObjectSilent(contact, attribute);
1220                            }
1221    
1222                            if (value != null) {
1223                                    BeanPropertiesUtil.setProperty(ldapUser, attribute, value);
1224                            }
1225                    }
1226    
1227                    updateLDAPUser(ldapUser.getUser(), ldapUser.getContact(), user);
1228    
1229                    user = UserLocalServiceUtil.updateUser(
1230                            user.getUserId(), password, StringPool.BLANK, StringPool.BLANK,
1231                            passwordReset, ldapUser.getReminderQueryQuestion(),
1232                            ldapUser.getReminderQueryAnswer(), ldapUser.getScreenName(),
1233                            ldapUser.getEmailAddress(), ldapUser.getFacebookId(),
1234                            ldapUser.getOpenId(), ldapUser.getLanguageId(),
1235                            ldapUser.getTimeZoneId(), ldapUser.getGreeting(),
1236                            ldapUser.getComments(), ldapUser.getFirstName(),
1237                            ldapUser.getMiddleName(), ldapUser.getLastName(),
1238                            ldapUser.getPrefixId(), ldapUser.getSuffixId(), ldapUser.isMale(),
1239                            birthdayMonth, birthdayDay, birthdayYear, ldapUser.getSmsSn(),
1240                            ldapUser.getAimSn(), ldapUser.getFacebookSn(), ldapUser.getIcqSn(),
1241                            ldapUser.getJabberSn(), ldapUser.getMsnSn(),
1242                            ldapUser.getMySpaceSn(), ldapUser.getSkypeSn(),
1243                            ldapUser.getTwitterSn(), ldapUser.getYmSn(), ldapUser.getJobTitle(),
1244                            ldapUser.getGroupIds(), ldapUser.getOrganizationIds(),
1245                            ldapUser.getRoleIds(), ldapUser.getUserGroupRoles(),
1246                            ldapUser.getUserGroupIds(), ldapUser.getServiceContext());
1247    
1248                    if (ldapUserModifiedDate != null) {
1249                            user = UserLocalServiceUtil.updateModifiedDate(
1250                                    user.getUserId(), ldapUserModifiedDate);
1251                    }
1252    
1253                    if (ldapUser.isUpdatePortrait()) {
1254                            byte[] portraitBytes = ldapUser.getPortraitBytes();
1255    
1256                            if ((portraitBytes != null) && (portraitBytes.length > 0)) {
1257                                    UserLocalServiceUtil.updatePortrait(
1258                                            user.getUserId(), portraitBytes);
1259                            }
1260                            else {
1261                                    UserLocalServiceUtil.deletePortrait(user.getUserId());
1262                            }
1263                    }
1264    
1265                    user = UserLocalServiceUtil.updateStatus(
1266                            user.getUserId(), ldapUser.getStatus());
1267    
1268                    return user;
1269            }
1270    
1271            private static final String[] _CONTACT_PROPERTY_NAMES = {
1272                    "aimSn", "facebookSn", "icqSn", "jabberSn", "male", "mySpaceSn",
1273                    "prefixId", "skypeSn", "smsSn", "suffixId", "twitterSn", "ymSn"
1274            };
1275    
1276            private static final String _IMPORT_BY_GROUP = "group";
1277    
1278            private static final String _IMPORT_BY_USER = "user";
1279    
1280            private static final String _USER_PASSWORD_SCREEN_NAME = "screenName";
1281    
1282            private static final String[] _USER_PROPERTY_NAMES = {
1283                    "comments", "greeting", "jobTitle", "languageId", "middleName",
1284                    "openId", "timeZoneId"
1285            };
1286    
1287            private static Log _log = LogFactoryUtil.getLog(
1288                    PortalLDAPImporterImpl.class);
1289    
1290            private LDAPToPortalConverter _ldapToPortalConverter;
1291            private PortalCache<String, Long> _portalCache = SingleVMPoolUtil.getCache(
1292                    PortalLDAPImporter.class.getName(), false);
1293    
1294    }