001    /**
002     * Copyright (c) 2000-2013 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.GroupFriendlyURLException;
018    import com.liferay.portal.NoSuchShardException;
019    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
020    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
021    import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
022    import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
023    import com.liferay.portal.kernel.dao.shard.ShardUtil;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.util.ArrayUtil;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.StringBundler;
029    import com.liferay.portal.kernel.util.StringPool;
030    import com.liferay.portal.kernel.util.UnicodeProperties;
031    import com.liferay.portal.model.Company;
032    import com.liferay.portal.model.Group;
033    import com.liferay.portal.model.GroupConstants;
034    import com.liferay.portal.model.LayoutSet;
035    import com.liferay.portal.model.Organization;
036    import com.liferay.portal.model.Shard;
037    import com.liferay.portal.model.User;
038    import com.liferay.portal.service.CompanyLocalServiceUtil;
039    import com.liferay.portal.service.GroupLocalServiceUtil;
040    import com.liferay.portal.service.ShardLocalServiceUtil;
041    import com.liferay.portal.service.UserLocalServiceUtil;
042    import com.liferay.portal.service.impl.GroupLocalServiceImpl;
043    import com.liferay.portal.util.PortalInstances;
044    import com.liferay.portal.util.PortalUtil;
045    import com.liferay.portal.util.PropsValues;
046    import com.liferay.portal.util.RobotsUtil;
047    
048    import java.sql.Connection;
049    import java.sql.PreparedStatement;
050    import java.sql.ResultSet;
051    
052    import java.util.Iterator;
053    import java.util.List;
054    import java.util.Set;
055    
056    /**
057     * @author Brian Wing Shun Chan
058     */
059    public class VerifyGroup extends VerifyProcess {
060    
061            @Override
062            protected void doVerify() throws Exception {
063                    verifyCompanyGroups();
064                    verifyNullFriendlyURLGroups();
065                    verifyOrganizationNames();
066                    verifyRobots();
067                    verifySites();
068                    verifyStagedGroups();
069                    verifyTree();
070            }
071    
072            protected String getRobots(LayoutSet layoutSet) {
073                    if (layoutSet == null) {
074                            return RobotsUtil.getDefaultRobots(null);
075                    }
076    
077                    String virtualHostname = StringPool.BLANK;
078    
079                    try {
080                            virtualHostname = layoutSet.getVirtualHostname();
081                    }
082                    catch (Exception e) {
083                    }
084    
085                    return GetterUtil.get(
086                            layoutSet.getSettingsProperty(
087                                    layoutSet.isPrivateLayout() + "-robots.txt"),
088                            RobotsUtil.getDefaultRobots(virtualHostname));
089            }
090    
091            protected void updateName(long groupId, String name) throws Exception {
092                    Connection con = null;
093                    PreparedStatement ps = null;
094    
095                    try {
096                            con = DataAccess.getUpgradeOptimizedConnection();
097    
098                            ps = con.prepareStatement(
099                                    "update Group_ set name = ? where groupId= " + groupId);
100    
101                            ps.setString(1, name);
102    
103                            ps.executeUpdate();
104                    }
105                    finally {
106                            DataAccess.cleanUp(con, ps);
107                    }
108            }
109    
110            protected void verifyCompanyGroups() throws Exception {
111                    List<Company> companies = CompanyLocalServiceUtil.getCompanies();
112    
113                    String currentShardName = ShardUtil.getCurrentShardName();
114    
115                    for (Company company : companies) {
116                            String shardName = null;
117    
118                            try {
119                                    shardName = company.getShardName();
120                            }
121                            catch (NoSuchShardException nsse) {
122                                    Shard shard = ShardLocalServiceUtil.addShard(
123                                            Company.class.getName(), company.getCompanyId(),
124                                            PropsValues.SHARD_DEFAULT_NAME);
125    
126                                    shardName = shard.getName();
127                            }
128    
129                            if (!ShardUtil.isEnabled() || shardName.equals(currentShardName)) {
130                                    GroupLocalServiceUtil.checkCompanyGroup(company.getCompanyId());
131    
132                                    GroupLocalServiceUtil.checkSystemGroups(company.getCompanyId());
133                            }
134                    }
135            }
136    
137            protected void verifyNullFriendlyURLGroups() throws Exception {
138                    List<Group> groups = GroupLocalServiceUtil.getNullFriendlyURLGroups();
139    
140                    for (Group group : groups) {
141                            String friendlyURL = StringPool.SLASH + group.getGroupId();
142    
143                            User user = null;
144    
145                            if (group.isCompany() && !group.isCompanyStagingGroup()) {
146                                    friendlyURL = GroupConstants.GLOBAL_FRIENDLY_URL;
147                            }
148                            else if (group.isUser()) {
149                                    user = UserLocalServiceUtil.getUserById(group.getClassPK());
150    
151                                    friendlyURL = StringPool.SLASH + user.getScreenName();
152                            }
153                            else if (group.getClassPK() > 0) {
154                                    friendlyURL = StringPool.SLASH + group.getClassPK();
155                            }
156    
157                            try {
158                                    GroupLocalServiceUtil.updateFriendlyURL(
159                                            group.getGroupId(), friendlyURL);
160                            }
161                            catch (GroupFriendlyURLException gfurle) {
162                                    if (user != null) {
163                                            long userId = user.getUserId();
164                                            String screenName = user.getScreenName();
165    
166                                            if (_log.isInfoEnabled()) {
167                                                    _log.info(
168                                                            "Updating user screen name " + screenName + " to " +
169                                                                    userId + " because it is generating an " +
170                                                                            "invalid friendly URL");
171                                            }
172    
173                                            UserLocalServiceUtil.updateScreenName(
174                                                    userId, String.valueOf(userId));
175                                    }
176                                    else {
177                                            _log.error("Invalid Friendly URL " + friendlyURL);
178    
179                                            throw gfurle;
180                                    }
181                            }
182                    }
183            }
184    
185            protected void verifyOrganizationNames() throws Exception {
186                    Connection con = null;
187                    PreparedStatement ps = null;
188                    ResultSet rs = null;
189    
190                    try {
191                            con = DataAccess.getUpgradeOptimizedConnection();
192    
193                            StringBundler sb = new StringBundler(5);
194    
195                            sb.append("select groupId, name from Group_ where name like '%");
196                            sb.append(GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX);
197                            sb.append("%' and name not like '%");
198                            sb.append(GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX);
199                            sb.append("'");
200    
201                            ps = con.prepareStatement(sb.toString());
202    
203                            rs = ps.executeQuery();
204    
205                            while (rs.next()) {
206                                    long groupId = rs.getLong("groupId");
207                                    String name = rs.getString("name");
208    
209                                    if (name.endsWith(
210                                                    GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX) ||
211                                            name.endsWith(
212                                                    GroupLocalServiceImpl.ORGANIZATION_STAGING_SUFFIX)) {
213    
214                                            continue;
215                                    }
216    
217                                    int pos = name.indexOf(
218                                            GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX);
219    
220                                    pos = name.indexOf(" ", pos + 1);
221    
222                                    String newName =
223                                            name.substring(pos + 1) +
224                                                    GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX;
225    
226                                    updateName(groupId, newName);
227                            }
228                    }
229                    finally {
230                            DataAccess.cleanUp(con, ps, rs);
231                    }
232            }
233    
234            protected void verifyRobots() throws Exception {
235                    List<Group> groups = GroupLocalServiceUtil.getLiveGroups();
236    
237                    for (Group group : groups) {
238                            LayoutSet privateLayoutSet = group.getPrivateLayoutSet();
239                            LayoutSet publicLayoutSet = group.getPublicLayoutSet();
240    
241                            String privateLayoutSetRobots = getRobots(privateLayoutSet);
242                            String publicLayoutSetRobots = getRobots(publicLayoutSet);
243    
244                            UnicodeProperties typeSettingsProperties =
245                                    group.getTypeSettingsProperties();
246    
247                            typeSettingsProperties.setProperty(
248                                    "true-robots.txt", privateLayoutSetRobots);
249                            typeSettingsProperties.setProperty(
250                                    "false-robots.txt", publicLayoutSetRobots);
251    
252                            GroupLocalServiceUtil.updateGroup(
253                                    group.getGroupId(), typeSettingsProperties.toString());
254                    }
255            }
256    
257            protected void verifySites() throws Exception {
258                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
259                            Group.class);
260    
261                    dynamicQuery.add(
262                            RestrictionsFactoryUtil.eq(
263                                    "classNameId", PortalUtil.getClassNameId(Organization.class)));
264                    dynamicQuery.add(RestrictionsFactoryUtil.eq("site", false));
265    
266                    List<Group> groups = GroupLocalServiceUtil.dynamicQuery(dynamicQuery);
267    
268                    for (Group group : groups) {
269                            if ((group.getPrivateLayoutsPageCount() > 0) ||
270                                    (group.getPublicLayoutsPageCount() > 0)) {
271    
272                                    group.setSite(true);
273    
274                                    GroupLocalServiceUtil.updateGroup(group);
275                            }
276                    }
277            }
278    
279            protected void verifyStagedGroups() throws Exception {
280                    List<Group> groups = GroupLocalServiceUtil.getLiveGroups();
281    
282                    for (Group group : groups) {
283                            if (!group.hasStagingGroup()) {
284                                    continue;
285                            }
286    
287                            UnicodeProperties typeSettingsProperties =
288                                    group.getTypeSettingsProperties();
289    
290                            typeSettingsProperties.setProperty(
291                                    "staged", Boolean.TRUE.toString());
292                            typeSettingsProperties.setProperty(
293                                    "stagedRemotely", Boolean.FALSE.toString());
294    
295                            verifyStagingTypeSettingsProperties(typeSettingsProperties);
296    
297                            GroupLocalServiceUtil.updateGroup(
298                                    group.getGroupId(), typeSettingsProperties.toString());
299    
300                            Group stagingGroup = group.getStagingGroup();
301    
302                            if (group.getClassNameId() != stagingGroup.getClassNameId()) {
303                                    stagingGroup.setClassNameId(group.getClassNameId());
304    
305                                    GroupLocalServiceUtil.updateGroup(stagingGroup);
306                            }
307                    }
308            }
309    
310            protected void verifyStagingTypeSettingsProperties(
311                    UnicodeProperties typeSettingsProperties) {
312    
313                    Set<String> keys = typeSettingsProperties.keySet();
314    
315                    Iterator<String> iterator = keys.iterator();
316    
317                    while (iterator.hasNext()) {
318                            String key = iterator.next();
319    
320                            if (ArrayUtil.contains(
321                                            _LEGACY_STAGED_PORTLET_TYPE_SETTINGS_KEYS, key)) {
322    
323                                    if (_log.isInfoEnabled()) {
324                                            _log.info("Removing type settings property " + key);
325                                    }
326    
327                                    iterator.remove();
328                            }
329                    }
330            }
331    
332            protected void verifyTree() throws Exception {
333                    long[] companyIds = PortalInstances.getCompanyIdsBySQL();
334    
335                    for (long companyId : companyIds) {
336                            GroupLocalServiceUtil.rebuildTree(companyId);
337                    }
338            }
339    
340            private static String[] _LEGACY_STAGED_PORTLET_TYPE_SETTINGS_KEYS = {
341                    "staged-portlet_39", "staged-portlet_54", "staged-portlet_56",
342                    "staged-portlet_59", "staged-portlet_107", "staged-portlet_108",
343                    "staged-portlet_110", "staged-portlet_166", "staged-portlet_169"
344            };
345    
346            private static Log _log = LogFactoryUtil.getLog(VerifyGroup.class);
347    
348    }