001    /**
002     * Copyright (c) 2000-present 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.verify;
016    
017    import com.liferay.portal.kernel.dao.jdbc.AutoBatchPreparedStatementUtil;
018    import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
019    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
020    import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
021    import com.liferay.portal.kernel.exception.GroupFriendlyURLException;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.model.Company;
025    import com.liferay.portal.kernel.model.Group;
026    import com.liferay.portal.kernel.model.GroupConstants;
027    import com.liferay.portal.kernel.model.LayoutSet;
028    import com.liferay.portal.kernel.model.Organization;
029    import com.liferay.portal.kernel.model.Role;
030    import com.liferay.portal.kernel.model.User;
031    import com.liferay.portal.kernel.model.UserGroup;
032    import com.liferay.portal.kernel.model.UserGroupGroupRole;
033    import com.liferay.portal.kernel.model.UserGroupRole;
034    import com.liferay.portal.kernel.service.CompanyLocalServiceUtil;
035    import com.liferay.portal.kernel.service.GroupLocalServiceUtil;
036    import com.liferay.portal.kernel.service.OrganizationLocalServiceUtil;
037    import com.liferay.portal.kernel.service.RoleLocalServiceUtil;
038    import com.liferay.portal.kernel.service.UserGroupGroupRoleLocalServiceUtil;
039    import com.liferay.portal.kernel.service.UserGroupLocalServiceUtil;
040    import com.liferay.portal.kernel.service.UserGroupRoleLocalServiceUtil;
041    import com.liferay.portal.kernel.service.UserLocalServiceUtil;
042    import com.liferay.portal.kernel.util.ArrayUtil;
043    import com.liferay.portal.kernel.util.GetterUtil;
044    import com.liferay.portal.kernel.util.ListUtil;
045    import com.liferay.portal.kernel.util.LoggingTimer;
046    import com.liferay.portal.kernel.util.PortalUtil;
047    import com.liferay.portal.kernel.util.StringBundler;
048    import com.liferay.portal.kernel.util.StringPool;
049    import com.liferay.portal.kernel.util.UnicodeProperties;
050    import com.liferay.portal.service.impl.GroupLocalServiceImpl;
051    import com.liferay.portal.util.PortalInstances;
052    import com.liferay.portal.util.RobotsUtil;
053    
054    import java.sql.PreparedStatement;
055    import java.sql.ResultSet;
056    
057    import java.util.Iterator;
058    import java.util.List;
059    import java.util.Set;
060    
061    /**
062     * @author Brian Wing Shun Chan
063     */
064    public class VerifyGroup extends VerifyProcess {
065    
066            @Override
067            protected void doVerify() throws Exception {
068                    verifyCompanyGroups();
069                    verifyNullFriendlyURLGroups();
070                    verifyOrganizationNames();
071                    verifyRobots();
072                    verifySites();
073                    verifyStagedGroups();
074                    verifyTree();
075            }
076    
077            protected String getRobots(LayoutSet layoutSet) {
078                    if (layoutSet == null) {
079                            return RobotsUtil.getDefaultRobots(null);
080                    }
081    
082                    String virtualHostname = StringPool.BLANK;
083    
084                    try {
085                            virtualHostname = layoutSet.getVirtualHostname();
086                    }
087                    catch (Exception e) {
088                    }
089    
090                    return GetterUtil.get(
091                            layoutSet.getSettingsProperty(
092                                    layoutSet.isPrivateLayout() + "-robots.txt"),
093                            RobotsUtil.getDefaultRobots(virtualHostname));
094            }
095    
096            protected void verifyCompanyGroups() throws Exception {
097                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
098                            List<Company> companies = CompanyLocalServiceUtil.getCompanies();
099    
100                            for (Company company : companies) {
101                                    GroupLocalServiceUtil.checkCompanyGroup(company.getCompanyId());
102    
103                                    GroupLocalServiceUtil.checkSystemGroups(company.getCompanyId());
104                            }
105                    }
106            }
107    
108            protected void verifyNullFriendlyURLGroups() throws Exception {
109                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
110                            List<Group> groups =
111                                    GroupLocalServiceUtil.getNullFriendlyURLGroups();
112    
113                            for (Group group : groups) {
114                                    String friendlyURL = StringPool.SLASH + group.getGroupId();
115    
116                                    User user = null;
117    
118                                    if (group.isCompany() && !group.isCompanyStagingGroup()) {
119                                            friendlyURL = GroupConstants.GLOBAL_FRIENDLY_URL;
120                                    }
121                                    else if (group.isUser()) {
122                                            user = UserLocalServiceUtil.getUserById(group.getClassPK());
123    
124                                            friendlyURL = StringPool.SLASH + user.getScreenName();
125                                    }
126                                    else if (group.getClassPK() > 0) {
127                                            friendlyURL = StringPool.SLASH + group.getClassPK();
128                                    }
129    
130                                    try {
131                                            GroupLocalServiceUtil.updateFriendlyURL(
132                                                    group.getGroupId(), friendlyURL);
133                                    }
134                                    catch (GroupFriendlyURLException gfurle) {
135                                            if (user != null) {
136                                                    long userId = user.getUserId();
137                                                    String screenName = user.getScreenName();
138    
139                                                    if (_log.isWarnEnabled()) {
140                                                            _log.warn(
141                                                                    "Updating user screen name " + screenName +
142                                                                            " to " + userId + " because it is " +
143                                                                            "generating an invalid friendly URL " +
144                                                                            friendlyURL);
145                                                    }
146    
147                                                    UserLocalServiceUtil.updateScreenName(
148                                                            userId, String.valueOf(userId));
149                                            }
150                                            else {
151                                                    _log.error("Invalid Friendly URL " + friendlyURL);
152    
153                                                    throw gfurle;
154                                            }
155                                    }
156                            }
157                    }
158            }
159    
160            protected void verifyOrganizationNames() throws Exception {
161                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
162                            StringBundler sb = new StringBundler(5);
163    
164                            sb.append("select groupId, name from Group_ where name like '%");
165                            sb.append(GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX);
166                            sb.append("%' and name not like '%");
167                            sb.append(GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX);
168                            sb.append("'");
169    
170                            try (PreparedStatement ps1 = connection.prepareStatement(
171                                            sb.toString());
172                                    PreparedStatement ps2 =
173                                            AutoBatchPreparedStatementUtil.concurrentAutoBatch(
174                                                    connection,
175                                                    "update Group_ set name = ? where groupId = ?");
176                                    ResultSet rs = ps1.executeQuery()) {
177    
178                                    while (rs.next()) {
179                                            long groupId = rs.getLong("groupId");
180                                            String name = rs.getString("name");
181    
182                                            if (name.endsWith(
183                                                            GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX) ||
184                                                    name.endsWith(
185                                                            GroupLocalServiceImpl.
186                                                                    ORGANIZATION_STAGING_SUFFIX)) {
187    
188                                                    continue;
189                                            }
190    
191                                            int pos = name.indexOf(
192                                                    GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX);
193    
194                                            pos = name.indexOf(" ", pos + 1);
195    
196                                            String newName =
197                                                    name.substring(pos + 1) +
198                                                            GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX;
199    
200                                            ps2.setString(1, newName);
201                                            ps2.setLong(2, groupId);
202    
203                                            ps2.addBatch();
204                                    }
205    
206                                    ps2.executeBatch();
207                            }
208                    }
209            }
210    
211            protected void verifyRobots() throws Exception {
212                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
213                            List<Group> groups = GroupLocalServiceUtil.getLiveGroups();
214    
215                            for (Group group : groups) {
216                                    LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
217                                    LayoutSet publicLayoutSet = group.getPublicLayoutSet();
218    
219                                    String privateLayoutSetRobots = getRobots(privateLayoutSet);
220                                    String publicLayoutSetRobots = getRobots(publicLayoutSet);
221    
222                                    UnicodeProperties typeSettingsProperties =
223                                            group.getTypeSettingsProperties();
224    
225                                    typeSettingsProperties.setProperty(
226                                            "true-robots.txt", privateLayoutSetRobots);
227                                    typeSettingsProperties.setProperty(
228                                            "false-robots.txt", publicLayoutSetRobots);
229    
230                                    GroupLocalServiceUtil.updateGroup(
231                                            group.getGroupId(), typeSettingsProperties.toString());
232                            }
233                    }
234            }
235    
236            protected void verifySites() throws Exception {
237                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
238                            ActionableDynamicQuery actionableDynamicQuery =
239                                    GroupLocalServiceUtil.getActionableDynamicQuery();
240    
241                            actionableDynamicQuery.setAddCriteriaMethod(
242                                    new ActionableDynamicQuery.AddCriteriaMethod() {
243    
244                                            @Override
245                                            public void addCriteria(DynamicQuery dynamicQuery) {
246                                                    dynamicQuery.add(
247                                                            RestrictionsFactoryUtil.eq(
248                                                                    "classNameId",
249                                                                    PortalUtil.getClassNameId(Organization.class)));
250                                                    dynamicQuery.add(
251                                                            RestrictionsFactoryUtil.eq("site", false));
252                                            }
253    
254                                    });
255                            actionableDynamicQuery.setParallel(true);
256                            actionableDynamicQuery.setPerformActionMethod(
257                                    new ActionableDynamicQuery.PerformActionMethod<Group>() {
258    
259                                            @Override
260                                            public void performAction(Group group) {
261                                                    if ((group.getPrivateLayoutsPageCount() > 0) ||
262                                                            (group.getPublicLayoutsPageCount() > 0)) {
263    
264                                                            group.setSite(true);
265    
266                                                            GroupLocalServiceUtil.updateGroup(group);
267                                                    }
268                                            }
269    
270                                    });
271    
272                            actionableDynamicQuery.performActions();
273                    }
274            }
275    
276            protected void verifyStagedGroups() throws Exception {
277                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
278                            List<Group> groups = GroupLocalServiceUtil.getLiveGroups();
279    
280                            for (Group group : groups) {
281                                    if (!group.hasStagingGroup()) {
282                                            continue;
283                                    }
284    
285                                    UnicodeProperties typeSettingsProperties =
286                                            group.getTypeSettingsProperties();
287    
288                                    typeSettingsProperties.setProperty(
289                                            "staged", Boolean.TRUE.toString());
290                                    typeSettingsProperties.setProperty(
291                                            "stagedRemotely", Boolean.FALSE.toString());
292    
293                                    verifyStagingTypeSettingsProperties(typeSettingsProperties);
294    
295                                    GroupLocalServiceUtil.updateGroup(
296                                            group.getGroupId(), typeSettingsProperties.toString());
297    
298                                    Group stagingGroup = group.getStagingGroup();
299    
300                                    if (group.getClassNameId() != stagingGroup.getClassNameId()) {
301                                            stagingGroup.setClassNameId(group.getClassNameId());
302    
303                                            GroupLocalServiceUtil.updateGroup(stagingGroup);
304                                    }
305    
306                                    if (!stagingGroup.isStagedRemotely()) {
307                                            verifyStagingGroupOrganizationMembership(stagingGroup);
308                                            verifyStagingGroupRoleMembership(stagingGroup);
309                                            verifyStagingGroupUserGroupMembership(stagingGroup);
310                                            verifyStagingGroupUserMembership(stagingGroup);
311                                            verifyStagingUserGroupRolesAssignments(stagingGroup);
312                                            verifyStagingUserGroupGroupRolesAssignments(stagingGroup);
313                                    }
314                            }
315                    }
316            }
317    
318            protected void verifyStagingGroupOrganizationMembership(Group stagingGroup)
319                    throws Exception {
320    
321                    List<Organization> stagingOrganizations =
322                            OrganizationLocalServiceUtil.getGroupOrganizations(
323                                    stagingGroup.getGroupId());
324    
325                    if (ListUtil.isEmpty(stagingOrganizations)) {
326                            return;
327                    }
328    
329                    List<Organization> liveOrganizations =
330                            OrganizationLocalServiceUtil.getGroupOrganizations(
331                                    stagingGroup.getLiveGroupId());
332    
333                    for (Organization stagingGroupOrganization : stagingOrganizations) {
334                            if (!liveOrganizations.contains(stagingGroupOrganization)) {
335                                    OrganizationLocalServiceUtil.addGroupOrganization(
336                                            stagingGroup.getLiveGroupId(), stagingGroupOrganization);
337                            }
338                    }
339    
340                    OrganizationLocalServiceUtil.clearGroupOrganizations(
341                            stagingGroup.getGroupId());
342            }
343    
344            protected void verifyStagingGroupRoleMembership(Group stagingGroup) {
345                    List<Role> stagingRoles = RoleLocalServiceUtil.getGroupRoles(
346                            stagingGroup.getGroupId());
347    
348                    if (ListUtil.isEmpty(stagingRoles)) {
349                            return;
350                    }
351    
352                    List<Role> liveRoles = RoleLocalServiceUtil.getGroupRoles(
353                            stagingGroup.getLiveGroupId());
354    
355                    for (Role stagingRole : stagingRoles) {
356                            if (!liveRoles.contains(stagingRole)) {
357                                    RoleLocalServiceUtil.addGroupRole(
358                                            stagingGroup.getLiveGroupId(), stagingRole);
359                            }
360                    }
361    
362                    RoleLocalServiceUtil.clearGroupRoles(stagingGroup.getGroupId());
363            }
364    
365            protected void verifyStagingGroupUserGroupMembership(Group stagingGroup) {
366                    List<UserGroup> stagingUserGroups =
367                            UserGroupLocalServiceUtil.getGroupUserGroups(
368                                    stagingGroup.getGroupId());
369    
370                    if (ListUtil.isEmpty(stagingUserGroups)) {
371                            return;
372                    }
373    
374                    List<UserGroup> liveUserGroups =
375                            UserGroupLocalServiceUtil.getGroupUserGroups(
376                                    stagingGroup.getLiveGroupId());
377    
378                    for (UserGroup stagingUserGroup : stagingUserGroups) {
379                            if (!liveUserGroups.contains(stagingUserGroup)) {
380                                    UserGroupLocalServiceUtil.addGroupUserGroup(
381                                            stagingGroup.getLiveGroupId(), stagingUserGroup);
382                            }
383                    }
384    
385                    UserGroupLocalServiceUtil.clearGroupUserGroups(
386                            stagingGroup.getGroupId());
387            }
388    
389            protected void verifyStagingGroupUserMembership(Group stagingGroup) {
390                    List<User> stagingGroupUsers = UserLocalServiceUtil.getGroupUsers(
391                            stagingGroup.getGroupId());
392    
393                    if (ListUtil.isEmpty(stagingGroupUsers)) {
394                            return;
395                    }
396    
397                    List<User> liveGroupUsers = UserLocalServiceUtil.getGroupUsers(
398                            stagingGroup.getLiveGroupId());
399    
400                    for (User stagingGroupUser : stagingGroupUsers) {
401                            if (!liveGroupUsers.contains(stagingGroupUser)) {
402                                    UserLocalServiceUtil.addGroupUser(
403                                            stagingGroup.getLiveGroupId(), stagingGroupUser);
404                            }
405                    }
406    
407                    UserLocalServiceUtil.clearGroupUsers(stagingGroup.getGroupId());
408            }
409    
410            protected void verifyStagingTypeSettingsProperties(
411                    UnicodeProperties typeSettingsProperties) {
412    
413                    Set<String> keys = typeSettingsProperties.keySet();
414    
415                    Iterator<String> iterator = keys.iterator();
416    
417                    while (iterator.hasNext()) {
418                            String key = iterator.next();
419    
420                            if (ArrayUtil.contains(
421                                            _LEGACY_STAGED_PORTLET_TYPE_SETTINGS_KEYS, key)) {
422    
423                                    if (_log.isInfoEnabled()) {
424                                            _log.info("Removing type settings property " + key);
425                                    }
426    
427                                    iterator.remove();
428                            }
429                    }
430            }
431    
432            protected void verifyStagingUserGroupGroupRolesAssignments(
433                    Group stagingGroup) {
434    
435                    DynamicQuery dynamicQuery =
436                            UserGroupGroupRoleLocalServiceUtil.dynamicQuery();
437    
438                    dynamicQuery.add(
439                            RestrictionsFactoryUtil.eq(
440                                    "id.groupId", stagingGroup.getGroupId()));
441    
442                    List<UserGroupGroupRole> stagingUserGroupGroupRoles =
443                            UserGroupGroupRoleLocalServiceUtil.dynamicQuery(dynamicQuery);
444    
445                    if (stagingUserGroupGroupRoles.isEmpty()) {
446                            return;
447                    }
448    
449                    dynamicQuery = UserGroupGroupRoleLocalServiceUtil.dynamicQuery();
450    
451                    dynamicQuery.add(
452                            RestrictionsFactoryUtil.eq(
453                                    "id.groupId", stagingGroup.getLiveGroupId()));
454    
455                    List<UserGroupGroupRole> liveUserGroupGroupRoles =
456                            UserGroupGroupRoleLocalServiceUtil.dynamicQuery(dynamicQuery);
457    
458                    for (UserGroupGroupRole userGroupGroupRole :
459                                    stagingUserGroupGroupRoles) {
460    
461                            userGroupGroupRole.setGroupId(stagingGroup.getLiveGroupId());
462    
463                            if (!liveUserGroupGroupRoles.contains(userGroupGroupRole)) {
464                                    UserGroupGroupRoleLocalServiceUtil.updateUserGroupGroupRole(
465                                            userGroupGroupRole);
466                            }
467                    }
468    
469                    UserGroupGroupRoleLocalServiceUtil.deleteUserGroupGroupRolesByGroupId(
470                            stagingGroup.getGroupId());
471            }
472    
473            protected void verifyStagingUserGroupRolesAssignments(Group stagingGroup) {
474                    List<UserGroupRole> stagingUserGroupRoles =
475                            UserGroupRoleLocalServiceUtil.getUserGroupRolesByGroup(
476                                    stagingGroup.getGroupId());
477    
478                    if (ListUtil.isEmpty(stagingUserGroupRoles)) {
479                            return;
480                    }
481    
482                    List<UserGroupRole> liveUserGroupRoles =
483                            UserGroupRoleLocalServiceUtil.getUserGroupRolesByGroup(
484                                    stagingGroup.getLiveGroupId());
485    
486                    for (UserGroupRole stagingUserGroupRole : stagingUserGroupRoles) {
487                            stagingUserGroupRole.setGroupId(stagingGroup.getLiveGroupId());
488    
489                            if (!liveUserGroupRoles.contains(stagingUserGroupRole)) {
490                                    UserGroupRoleLocalServiceUtil.updateUserGroupRole(
491                                            stagingUserGroupRole);
492                            }
493                    }
494    
495                    UserGroupRoleLocalServiceUtil.deleteUserGroupRolesByGroupId(
496                            stagingGroup.getGroupId());
497            }
498    
499            protected void verifyTree() throws Exception {
500                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
501                            long[] companyIds = PortalInstances.getCompanyIdsBySQL();
502    
503                            for (long companyId : companyIds) {
504                                    GroupLocalServiceUtil.rebuildTree(companyId);
505                            }
506                    }
507            }
508    
509            private static final String[] _LEGACY_STAGED_PORTLET_TYPE_SETTINGS_KEYS = {
510                    "staged-portlet_39", "staged-portlet_54", "staged-portlet_56",
511                    "staged-portlet_59", "staged-portlet_107", "staged-portlet_108",
512                    "staged-portlet_110", "staged-portlet_166", "staged-portlet_169"
513            };
514    
515            private static final Log _log = LogFactoryUtil.getLog(VerifyGroup.class);
516    
517    }