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.portlet.admin.action;
016    
017    import com.liferay.mail.service.MailServiceUtil;
018    import com.liferay.portal.captcha.CaptchaImpl;
019    import com.liferay.portal.captcha.recaptcha.ReCaptchaImpl;
020    import com.liferay.portal.captcha.simplecaptcha.SimpleCaptchaImpl;
021    import com.liferay.portal.convert.ConvertException;
022    import com.liferay.portal.convert.ConvertProcess;
023    import com.liferay.portal.kernel.cache.CacheRegistryUtil;
024    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
025    import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
026    import com.liferay.portal.kernel.captcha.Captcha;
027    import com.liferay.portal.kernel.captcha.CaptchaUtil;
028    import com.liferay.portal.kernel.cluster.Address;
029    import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
030    import com.liferay.portal.kernel.cluster.ClusterLink;
031    import com.liferay.portal.kernel.cluster.ClusterRequest;
032    import com.liferay.portal.kernel.concurrent.ThreadPoolExecutor;
033    import com.liferay.portal.kernel.dao.shard.ShardUtil;
034    import com.liferay.portal.kernel.exception.SystemException;
035    import com.liferay.portal.kernel.executor.PortalExecutorManagerUtil;
036    import com.liferay.portal.kernel.image.GhostscriptUtil;
037    import com.liferay.portal.kernel.image.ImageMagickUtil;
038    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
039    import com.liferay.portal.kernel.io.unsync.UnsyncPrintWriter;
040    import com.liferay.portal.kernel.json.JSONFactoryUtil;
041    import com.liferay.portal.kernel.json.JSONObject;
042    import com.liferay.portal.kernel.log.Log;
043    import com.liferay.portal.kernel.log.LogFactoryUtil;
044    import com.liferay.portal.kernel.log.SanitizerLogWrapper;
045    import com.liferay.portal.kernel.mail.Account;
046    import com.liferay.portal.kernel.messaging.BaseAsyncDestination;
047    import com.liferay.portal.kernel.messaging.Destination;
048    import com.liferay.portal.kernel.messaging.DestinationNames;
049    import com.liferay.portal.kernel.messaging.MessageBus;
050    import com.liferay.portal.kernel.messaging.MessageBusUtil;
051    import com.liferay.portal.kernel.messaging.proxy.MessageValuesThreadLocal;
052    import com.liferay.portal.kernel.scripting.ScriptingException;
053    import com.liferay.portal.kernel.scripting.ScriptingHelperUtil;
054    import com.liferay.portal.kernel.scripting.ScriptingUtil;
055    import com.liferay.portal.kernel.search.Indexer;
056    import com.liferay.portal.kernel.search.SearchEngineUtil;
057    import com.liferay.portal.kernel.servlet.DirectServletRegistryUtil;
058    import com.liferay.portal.kernel.servlet.SessionErrors;
059    import com.liferay.portal.kernel.servlet.SessionMessages;
060    import com.liferay.portal.kernel.util.CharPool;
061    import com.liferay.portal.kernel.util.Constants;
062    import com.liferay.portal.kernel.util.InstancePool;
063    import com.liferay.portal.kernel.util.MethodHandler;
064    import com.liferay.portal.kernel.util.MethodKey;
065    import com.liferay.portal.kernel.util.ParamUtil;
066    import com.liferay.portal.kernel.util.ProgressStatusConstants;
067    import com.liferay.portal.kernel.util.ProgressTracker;
068    import com.liferay.portal.kernel.util.PropsKeys;
069    import com.liferay.portal.kernel.util.StringBundler;
070    import com.liferay.portal.kernel.util.StringPool;
071    import com.liferay.portal.kernel.util.StringUtil;
072    import com.liferay.portal.kernel.util.ThreadUtil;
073    import com.liferay.portal.kernel.util.Time;
074    import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
075    import com.liferay.portal.kernel.util.Validator;
076    import com.liferay.portal.kernel.xuggler.XugglerUtil;
077    import com.liferay.portal.model.Portlet;
078    import com.liferay.portal.search.SearchEngineInitializer;
079    import com.liferay.portal.search.lucene.LuceneHelperUtil;
080    import com.liferay.portal.search.lucene.cluster.LuceneClusterUtil;
081    import com.liferay.portal.security.auth.PrincipalException;
082    import com.liferay.portal.security.lang.DoPrivilegedBean;
083    import com.liferay.portal.security.membershippolicy.OrganizationMembershipPolicy;
084    import com.liferay.portal.security.membershippolicy.OrganizationMembershipPolicyFactoryUtil;
085    import com.liferay.portal.security.membershippolicy.RoleMembershipPolicy;
086    import com.liferay.portal.security.membershippolicy.RoleMembershipPolicyFactoryUtil;
087    import com.liferay.portal.security.membershippolicy.SiteMembershipPolicy;
088    import com.liferay.portal.security.membershippolicy.SiteMembershipPolicyFactoryUtil;
089    import com.liferay.portal.security.membershippolicy.UserGroupMembershipPolicy;
090    import com.liferay.portal.security.membershippolicy.UserGroupMembershipPolicyFactoryUtil;
091    import com.liferay.portal.security.permission.PermissionChecker;
092    import com.liferay.portal.service.PortletLocalServiceUtil;
093    import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
094    import com.liferay.portal.struts.ActionConstants;
095    import com.liferay.portal.struts.PortletAction;
096    import com.liferay.portal.theme.ThemeDisplay;
097    import com.liferay.portal.upload.UploadServletRequestImpl;
098    import com.liferay.portal.util.MaintenanceUtil;
099    import com.liferay.portal.util.Portal;
100    import com.liferay.portal.util.PortalInstances;
101    import com.liferay.portal.util.PrefsPropsUtil;
102    import com.liferay.portal.util.PropsValues;
103    import com.liferay.portal.util.ShutdownUtil;
104    import com.liferay.portal.util.WebKeys;
105    import com.liferay.portlet.ActionResponseImpl;
106    import com.liferay.portlet.admin.util.CleanUpPermissionsUtil;
107    import com.liferay.portlet.documentlibrary.util.DLPreviewableProcessor;
108    import com.liferay.util.log4j.Log4JUtil;
109    
110    import java.io.File;
111    
112    import java.util.Enumeration;
113    import java.util.HashSet;
114    import java.util.List;
115    import java.util.Map;
116    import java.util.Set;
117    import java.util.concurrent.CountDownLatch;
118    import java.util.concurrent.TimeUnit;
119    
120    import javax.portlet.ActionRequest;
121    import javax.portlet.ActionResponse;
122    import javax.portlet.PortletConfig;
123    import javax.portlet.PortletContext;
124    import javax.portlet.PortletPreferences;
125    import javax.portlet.PortletSession;
126    import javax.portlet.PortletURL;
127    import javax.portlet.WindowState;
128    
129    import org.apache.log4j.Level;
130    import org.apache.struts.action.ActionForm;
131    import org.apache.struts.action.ActionMapping;
132    
133    /**
134     * @author Brian Wing Shun Chan
135     * @author Shuyang Zhou
136     */
137    public class EditServerAction extends PortletAction {
138    
139            @Override
140            public void processAction(
141                            ActionMapping actionMapping, ActionForm actionForm,
142                            PortletConfig portletConfig, ActionRequest actionRequest,
143                            ActionResponse actionResponse)
144                    throws Exception {
145    
146                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
147                            WebKeys.THEME_DISPLAY);
148    
149                    PermissionChecker permissionChecker =
150                            themeDisplay.getPermissionChecker();
151    
152                    if (!permissionChecker.isOmniadmin()) {
153                            SessionErrors.add(
154                                    actionRequest, PrincipalException.class.getName());
155    
156                            setForward(actionRequest, "portlet.admin.error");
157    
158                            return;
159                    }
160    
161                    PortletPreferences portletPreferences = PrefsPropsUtil.getPreferences();
162    
163                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
164    
165                    String redirect = null;
166    
167                    if (cmd.equals("addLogLevel")) {
168                            addLogLevel(actionRequest);
169                    }
170                    else if (cmd.equals("cacheDb")) {
171                            cacheDb();
172                    }
173                    else if (cmd.equals("cacheMulti")) {
174                            cacheMulti();
175                    }
176                    else if (cmd.equals("cacheServlet")) {
177                            cacheServlet();
178                    }
179                    else if (cmd.equals("cacheSingle")) {
180                            cacheSingle();
181                    }
182                    else if (cmd.equals("cleanUpPermissions")) {
183                            CleanUpPermissionsUtil.cleanUpAddToPagePermissions(actionRequest);
184                    }
185                    else if (cmd.startsWith("convertProcess.")) {
186                            redirect = convertProcess(actionRequest, actionResponse, cmd);
187                    }
188                    else if (cmd.equals("dlPreviews")) {
189                            DLPreviewableProcessor.deleteFiles();
190                    }
191                    else if (cmd.equals("gc")) {
192                            gc();
193                    }
194                    else if (cmd.equals("installXuggler")) {
195                            installXuggler(actionRequest, actionResponse);
196    
197                            setForward(actionRequest, ActionConstants.COMMON_NULL);
198    
199                            return;
200                    }
201                    else if (cmd.equals("reindex")) {
202                            reindex(actionRequest);
203                    }
204                    else if (cmd.equals("reindexDictionaries")) {
205                            reindexDictionaries(actionRequest);
206                    }
207                    else if (cmd.equals("runScript")) {
208                            runScript(portletConfig, actionRequest, actionResponse);
209                    }
210                    else if (cmd.equals("shutdown")) {
211                            shutdown(actionRequest);
212                    }
213                    else if (cmd.equals("threadDump")) {
214                            threadDump();
215                    }
216                    else if (cmd.equals("updateCaptcha")) {
217                            updateCaptcha(actionRequest, portletPreferences);
218                    }
219                    else if (cmd.equals("updateExternalServices")) {
220                            updateExternalServices(actionRequest, portletPreferences);
221                    }
222                    else if (cmd.equals("updateFileUploads")) {
223                            updateFileUploads(actionRequest, portletPreferences);
224                    }
225                    else if (cmd.equals("updateLogLevels")) {
226                            updateLogLevels(actionRequest);
227                    }
228                    else if (cmd.equals("updateMail")) {
229                            updateMail(actionRequest, portletPreferences);
230                    }
231                    else if (cmd.equals("verifyMembershipPolicies")) {
232                            verifyMembershipPolicies();
233                    }
234                    else if (cmd.equals("verifyPluginTables")) {
235                            verifyPluginTables();
236                    }
237    
238                    sendRedirect(actionRequest, actionResponse, redirect);
239            }
240    
241            protected void addLogLevel(ActionRequest actionRequest) throws Exception {
242                    String loggerName = ParamUtil.getString(actionRequest, "loggerName");
243                    String priority = ParamUtil.getString(actionRequest, "priority");
244    
245                    Log4JUtil.setLevel(loggerName, priority, true);
246            }
247    
248            protected void cacheDb() throws Exception {
249                    CacheRegistryUtil.clear();
250            }
251    
252            protected void cacheMulti() throws Exception {
253                    MultiVMPoolUtil.clear();
254            }
255    
256            protected void cacheServlet() throws Exception {
257                    DirectServletRegistryUtil.clearServlets();
258            }
259    
260            protected void cacheSingle() throws Exception {
261                    SingleVMPoolUtil.clear();
262            }
263    
264            protected String convertProcess(
265                            ActionRequest actionRequest, ActionResponse actionResponse,
266                            String cmd)
267                    throws Exception {
268    
269                    ActionResponseImpl actionResponseImpl =
270                            (ActionResponseImpl)actionResponse;
271    
272                    PortletSession portletSession = actionRequest.getPortletSession();
273    
274                    String className = StringUtil.replaceFirst(
275                            cmd, "convertProcess.", StringPool.BLANK);
276    
277                    ConvertProcess convertProcess = (ConvertProcess)InstancePool.get(
278                            className);
279    
280                    String[] parameters = convertProcess.getParameterNames();
281    
282                    if (parameters != null) {
283                            String[] values = new String[parameters.length];
284    
285                            for (int i = 0; i < parameters.length; i++) {
286                                    String parameter =
287                                            className + StringPool.PERIOD + parameters[i];
288    
289                                    if (parameters[i].contains(StringPool.EQUAL)) {
290                                            String[] parameterPair = StringUtil.split(
291                                                    parameters[i], CharPool.EQUAL);
292    
293                                            parameter =
294                                                    className + StringPool.PERIOD + parameterPair[0];
295                                    }
296    
297                                    values[i] = ParamUtil.getString(actionRequest, parameter);
298                            }
299    
300                            convertProcess.setParameterValues(values);
301                    }
302    
303                    try {
304                            convertProcess.validate();
305                    }
306                    catch (ConvertException ce) {
307                            SessionErrors.add(actionRequest, ce.getClass(), ce);
308    
309                            return null;
310                    }
311    
312                    String path = convertProcess.getPath();
313    
314                    if (path != null) {
315                            PortletURL portletURL = actionResponseImpl.createRenderURL();
316    
317                            portletURL.setParameter("struts_action", path);
318                            portletURL.setWindowState(WindowState.MAXIMIZED);
319    
320                            return portletURL.toString();
321                    }
322    
323                    MaintenanceUtil.maintain(portletSession.getId(), className);
324    
325                    MessageBusUtil.sendMessage(DestinationNames.CONVERT_PROCESS, className);
326    
327                    return null;
328            }
329    
330            protected void gc() throws Exception {
331                    Runtime.getRuntime().gc();
332            }
333    
334            protected String getFileExtensions(
335                    ActionRequest actionRequest, String name) {
336    
337                    String value = ParamUtil.getString(actionRequest, name);
338    
339                    return value.replace(", .", ",.");
340            }
341    
342            protected void installXuggler(
343                            ActionRequest actionRequest, ActionResponse actionResponse)
344                    throws Exception {
345    
346                    ProgressTracker progressTracker = new ProgressTracker(
347                            WebKeys.XUGGLER_INSTALL_STATUS);
348    
349                    progressTracker.addProgress(
350                            ProgressStatusConstants.DOWNLOADING, 15, "downloading-xuggler");
351                    progressTracker.addProgress(
352                            ProgressStatusConstants.COPYING, 70, "copying-xuggler-files");
353    
354                    progressTracker.initialize(actionRequest);
355    
356                    String jarName = ParamUtil.getString(actionRequest, "jarName");
357    
358                    try {
359                            XugglerUtil.installNativeLibraries(jarName, progressTracker);
360    
361                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
362    
363                            jsonObject.put("success", Boolean.TRUE);
364    
365                            writeJSON(actionRequest, actionResponse, jsonObject);
366                    }
367                    catch (Exception e) {
368                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
369    
370                            jsonObject.put("exception", e.getMessage());
371                            jsonObject.put("success", Boolean.FALSE);
372    
373                            writeJSON(actionRequest, actionResponse, jsonObject);
374                    }
375    
376                    progressTracker.finish(actionRequest);
377            }
378    
379            protected void reindex(ActionRequest actionRequest) throws Exception {
380                    String portletId = ParamUtil.getString(actionRequest, "portletId");
381    
382                    long[] companyIds = PortalInstances.getCompanyIds();
383    
384                    if (LuceneHelperUtil.isLoadIndexFromClusterEnabled()) {
385                            MessageValuesThreadLocal.setValue(
386                                    ClusterLink.CLUSTER_FORWARD_MESSAGE, true);
387                    }
388    
389                    Set<String> usedSearchEngineIds = new HashSet<String>();
390    
391                    if (Validator.isNull(portletId)) {
392                            for (long companyId : companyIds) {
393                                    try {
394                                            SearchEngineInitializer searchEngineInitializer =
395                                                    new SearchEngineInitializer(companyId);
396    
397                                            searchEngineInitializer.reindex();
398    
399                                            usedSearchEngineIds.addAll(
400                                                    searchEngineInitializer.getUsedSearchEngineIds());
401                                    }
402                                    catch (Exception e) {
403                                            _log.error(e, e);
404                                    }
405                            }
406                    }
407                    else {
408                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
409                                    companyIds[0], portletId);
410    
411                            if (portlet == null) {
412                                    return;
413                            }
414    
415                            List<Indexer> indexers = portlet.getIndexerInstances();
416    
417                            if (indexers == null) {
418                                    return;
419                            }
420    
421                            Set<String> searchEngineIds = new HashSet<String>();
422    
423                            for (Indexer indexer : indexers) {
424                                    searchEngineIds.add(indexer.getSearchEngineId());
425                            }
426    
427                            for (String searchEngineId : searchEngineIds) {
428                                    for (long companyId : companyIds) {
429                                            SearchEngineUtil.deletePortletDocuments(
430                                                    searchEngineId, companyId, portletId, true);
431                                    }
432                            }
433    
434                            for (Indexer indexer : indexers) {
435                                    for (long companyId : companyIds) {
436                                            ShardUtil.pushCompanyService(companyId);
437    
438                                            try {
439                                                    indexer.reindex(
440                                                            new String[] {String.valueOf(companyId)});
441    
442                                                    usedSearchEngineIds.add(indexer.getSearchEngineId());
443                                            }
444                                            catch (Exception e) {
445                                                    _log.error(e, e);
446                                            }
447                                            finally {
448                                                    ShardUtil.popCompanyService();
449                                            }
450                                    }
451                            }
452                    }
453    
454                    if (!LuceneHelperUtil.isLoadIndexFromClusterEnabled()) {
455                            return;
456                    }
457    
458                    Set<BaseAsyncDestination> searchWriterDestinations =
459                            new HashSet<BaseAsyncDestination>();
460    
461                    MessageBus messageBus = MessageBusUtil.getMessageBus();
462    
463                    for (String usedSearchEngineId : usedSearchEngineIds) {
464                            String searchWriterDestinationName =
465                                    SearchEngineUtil.getSearchWriterDestinationName(
466                                            usedSearchEngineId);
467    
468                            Destination destination = messageBus.getDestination(
469                                    searchWriterDestinationName);
470    
471                            if (destination instanceof BaseAsyncDestination) {
472                                    BaseAsyncDestination baseAsyncDestination =
473                                            (BaseAsyncDestination)destination;
474    
475                                    searchWriterDestinations.add(baseAsyncDestination);
476                            }
477                    }
478    
479                    submitClusterIndexLoadingSyncJob(searchWriterDestinations, companyIds);
480            }
481    
482            protected void reindexDictionaries(ActionRequest actionRequest)
483                    throws Exception {
484    
485                    long[] companyIds = PortalInstances.getCompanyIds();
486    
487                    for (long companyId : companyIds) {
488                            SearchEngineUtil.indexQuerySuggestionDictionaries(companyId);
489                            SearchEngineUtil.indexSpellCheckerDictionaries(companyId);
490                    }
491            }
492    
493            protected void runScript(
494                            PortletConfig portletConfig, ActionRequest actionRequest,
495                            ActionResponse actionResponse)
496                    throws Exception {
497    
498                    String language = ParamUtil.getString(actionRequest, "language");
499                    String script = ParamUtil.getString(actionRequest, "script");
500    
501                    PortletContext portletContext = portletConfig.getPortletContext();
502    
503                    Map<String, Object> portletObjects =
504                            ScriptingHelperUtil.getPortletObjects(
505                                    portletConfig, portletContext, actionRequest, actionResponse);
506    
507                    UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
508                            new UnsyncByteArrayOutputStream();
509    
510                    UnsyncPrintWriter unsyncPrintWriter = UnsyncPrintWriterPool.borrow(
511                            unsyncByteArrayOutputStream);
512    
513                    portletObjects.put("out", unsyncPrintWriter);
514    
515                    try {
516                            SessionMessages.add(actionRequest, "language", language);
517                            SessionMessages.add(actionRequest, "script", script);
518    
519                            ScriptingUtil.exec(
520                                    null, portletObjects, language, script, StringPool.EMPTY_ARRAY);
521    
522                            unsyncPrintWriter.flush();
523    
524                            SessionMessages.add(
525                                    actionRequest, "scriptOutput",
526                                    unsyncByteArrayOutputStream.toString());
527                    }
528                    catch (ScriptingException se) {
529                            SessionErrors.add(
530                                    actionRequest, ScriptingException.class.getName(), se);
531    
532                            Log log = SanitizerLogWrapper.allowCRLF(_log);
533    
534                            log.error(se.getMessage());
535                    }
536            }
537    
538            protected void shutdown(ActionRequest actionRequest) throws Exception {
539                    if (ShutdownUtil.isInProcess()) {
540                            ShutdownUtil.cancel();
541                    }
542                    else {
543                            long minutes =
544                                    ParamUtil.getInteger(actionRequest, "minutes") * Time.MINUTE;
545    
546                            if (minutes <= 0) {
547                                    SessionErrors.add(actionRequest, "shutdownMinutes");
548                            }
549                            else {
550                                    String message = ParamUtil.getString(actionRequest, "message");
551    
552                                    ShutdownUtil.shutdown(minutes, message);
553                            }
554                    }
555            }
556    
557            protected void submitClusterIndexLoadingSyncJob(
558                            Set<BaseAsyncDestination> baseAsyncDestinations, long[] companyIds)
559                    throws Exception {
560    
561                    if (_log.isInfoEnabled()) {
562                            StringBundler sb = new StringBundler(
563                                    baseAsyncDestinations.size() + 1);
564    
565                            sb.append("[");
566    
567                            for (BaseAsyncDestination baseAsyncDestination :
568                                            baseAsyncDestinations) {
569    
570                                    sb.append(baseAsyncDestination.getName());
571                                    sb.append(", ");
572                            }
573    
574                            sb.setStringAt("]", sb.index() - 1);
575    
576                            _log.info(
577                                    "Synchronizecluster index loading for destinations " +
578                                            sb.toString());
579                    }
580    
581                    int totalWorkersMaxSize = 0;
582    
583                    for (BaseAsyncDestination baseAsyncDestination :
584                                    baseAsyncDestinations) {
585    
586                            totalWorkersMaxSize += baseAsyncDestination.getWorkersMaxSize();
587                    }
588    
589                    if (_log.isInfoEnabled()) {
590                            _log.info(
591                                    "There are " + totalWorkersMaxSize +
592                                            " synchronization threads");
593                    }
594    
595                    CountDownLatch countDownLatch = new CountDownLatch(
596                            totalWorkersMaxSize + 1);
597    
598                    ClusterLoadingSyncJob slaveClusterLoadingSyncJob =
599                            new ClusterLoadingSyncJob(companyIds, countDownLatch, false);
600    
601                    for (BaseAsyncDestination baseAsyncDestination :
602                                    baseAsyncDestinations) {
603    
604                            ThreadPoolExecutor threadPoolExecutor =
605                                    PortalExecutorManagerUtil.getPortalExecutor(
606                                            baseAsyncDestination.getName());
607    
608                            for (int i = 0; i < baseAsyncDestination.getWorkersMaxSize(); i++) {
609                                    threadPoolExecutor.execute(slaveClusterLoadingSyncJob);
610                            }
611                    }
612    
613                    ClusterLoadingSyncJob masterClusterLoadingSyncJob =
614                            new ClusterLoadingSyncJob(companyIds, countDownLatch, true);
615    
616                    ThreadPoolExecutor threadPoolExecutor =
617                            PortalExecutorManagerUtil.getPortalExecutor(
618                                    EditServerAction.class.getName());
619    
620                    threadPoolExecutor.execute(masterClusterLoadingSyncJob);
621            }
622    
623            protected void threadDump() throws Exception {
624                    if (_log.isInfoEnabled()) {
625                            Log log = SanitizerLogWrapper.allowCRLF(_log);
626    
627                            log.info(ThreadUtil.threadDump());
628                    }
629                    else {
630                            Class<?> clazz = getClass();
631    
632                            _log.error(
633                                    "Thread dumps require the log level to be at least INFO for " +
634                                            clazz.getName());
635                    }
636            }
637    
638            protected void updateCaptcha(
639                            ActionRequest actionRequest, PortletPreferences portletPreferences)
640                    throws Exception {
641    
642                    boolean reCaptchaEnabled = ParamUtil.getBoolean(
643                            actionRequest, "reCaptchaEnabled");
644                    String reCaptchaPrivateKey = ParamUtil.getString(
645                            actionRequest, "reCaptchaPrivateKey");
646                    String reCaptchaPublicKey = ParamUtil.getString(
647                            actionRequest, "reCaptchaPublicKey");
648    
649                    Captcha captcha = null;
650    
651                    if (reCaptchaEnabled) {
652                            captcha = new ReCaptchaImpl();
653                    }
654                    else {
655                            captcha = new SimpleCaptchaImpl();
656                    }
657    
658                    validateCaptcha(actionRequest);
659    
660                    if (SessionErrors.isEmpty(actionRequest)) {
661                            portletPreferences.setValue(
662                                    PropsKeys.CAPTCHA_ENGINE_IMPL, captcha.getClass().getName());
663                            portletPreferences.setValue(
664                                    PropsKeys.CAPTCHA_ENGINE_RECAPTCHA_KEY_PRIVATE,
665                                    reCaptchaPrivateKey);
666                            portletPreferences.setValue(
667                                    PropsKeys.CAPTCHA_ENGINE_RECAPTCHA_KEY_PUBLIC,
668                                    reCaptchaPublicKey);
669    
670                            portletPreferences.store();
671    
672                            CaptchaImpl captchaImpl = null;
673    
674                            Captcha currentCaptcha = CaptchaUtil.getCaptcha();
675    
676                            if (currentCaptcha instanceof DoPrivilegedBean) {
677                                    DoPrivilegedBean doPrivilegedBean =
678                                            (DoPrivilegedBean)currentCaptcha;
679    
680                                    captchaImpl = (CaptchaImpl)doPrivilegedBean.getActualBean();
681                            }
682                            else {
683                                    captchaImpl = (CaptchaImpl)currentCaptcha;
684                            }
685    
686                            captchaImpl.setCaptcha(captcha);
687                    }
688            }
689    
690            protected void updateExternalServices(
691                            ActionRequest actionRequest, PortletPreferences portletPreferences)
692                    throws Exception {
693    
694                    boolean imageMagickEnabled = ParamUtil.getBoolean(
695                            actionRequest, "imageMagickEnabled");
696                    String imageMagickPath = ParamUtil.getString(
697                            actionRequest, "imageMagickPath");
698                    boolean openOfficeEnabled = ParamUtil.getBoolean(
699                            actionRequest, "openOfficeEnabled");
700                    int openOfficePort = ParamUtil.getInteger(
701                            actionRequest, "openOfficePort");
702                    boolean xugglerEnabled = ParamUtil.getBoolean(
703                            actionRequest, "xugglerEnabled");
704    
705                    portletPreferences.setValue(
706                            PropsKeys.IMAGEMAGICK_ENABLED, String.valueOf(imageMagickEnabled));
707                    portletPreferences.setValue(
708                            PropsKeys.IMAGEMAGICK_GLOBAL_SEARCH_PATH, imageMagickPath);
709                    portletPreferences.setValue(
710                            PropsKeys.OPENOFFICE_SERVER_ENABLED,
711                            String.valueOf(openOfficeEnabled));
712                    portletPreferences.setValue(
713                            PropsKeys.OPENOFFICE_SERVER_PORT, String.valueOf(openOfficePort));
714                    portletPreferences.setValue(
715                            PropsKeys.XUGGLER_ENABLED, String.valueOf(xugglerEnabled));
716    
717                    Enumeration<String> enu = actionRequest.getParameterNames();
718    
719                    while (enu.hasMoreElements()) {
720                            String name = enu.nextElement();
721    
722                            if (name.startsWith("imageMagickLimit")) {
723                                    String key = StringUtil.toLowerCase(
724                                            name.substring(16, name.length()));
725                                    String value = ParamUtil.getString(actionRequest, name);
726    
727                                    portletPreferences.setValue(
728                                            PropsKeys.IMAGEMAGICK_RESOURCE_LIMIT + key, value);
729                            }
730                    }
731    
732                    portletPreferences.store();
733    
734                    GhostscriptUtil.reset();
735                    ImageMagickUtil.reset();
736            }
737    
738            protected void updateFileUploads(
739                            ActionRequest actionRequest, PortletPreferences portletPreferences)
740                    throws Exception {
741    
742                    long dlFileEntryPreviewableProcessorMaxSize = ParamUtil.getLong(
743                            actionRequest, "dlFileEntryPreviewableProcessorMaxSize");
744                    long dlFileEntryThumbnailMaxHeight = ParamUtil.getLong(
745                            actionRequest, "dlFileEntryThumbnailMaxHeight");
746                    long dlFileEntryThumbnailMaxWidth = ParamUtil.getLong(
747                            actionRequest, "dlFileEntryThumbnailMaxWidth");
748                    String dlFileExtensions = getFileExtensions(
749                            actionRequest, "dlFileExtensions");
750                    long dlFileMaxSize = ParamUtil.getLong(actionRequest, "dlFileMaxSize");
751                    String journalImageExtensions = getFileExtensions(
752                            actionRequest, "journalImageExtensions");
753                    long journalImageSmallMaxSize = ParamUtil.getLong(
754                            actionRequest, "journalImageSmallMaxSize");
755                    String shoppingImageExtensions = getFileExtensions(
756                            actionRequest, "shoppingImageExtensions");
757                    long scImageMaxSize = ParamUtil.getLong(
758                            actionRequest, "scImageMaxSize");
759                    long scImageThumbnailMaxHeight = ParamUtil.getLong(
760                            actionRequest, "scImageThumbnailMaxHeight");
761                    long scImageThumbnailMaxWidth = ParamUtil.getLong(
762                            actionRequest, "scImageThumbnailMaxWidth");
763                    long shoppingImageLargeMaxSize = ParamUtil.getLong(
764                            actionRequest, "shoppingImageLargeMaxSize");
765                    long shoppingImageMediumMaxSize = ParamUtil.getLong(
766                            actionRequest, "shoppingImageMediumMaxSize");
767                    long shoppingImageSmallMaxSize = ParamUtil.getLong(
768                            actionRequest, "shoppingImageSmallMaxSize");
769                    long uploadServletRequestImplMaxSize = ParamUtil.getLong(
770                            actionRequest, "uploadServletRequestImplMaxSize");
771                    String uploadServletRequestImplTempDir = ParamUtil.getString(
772                            actionRequest, "uploadServletRequestImplTempDir");
773                    long usersImageMaxSize = ParamUtil.getLong(
774                            actionRequest, "usersImageMaxSize");
775    
776                    portletPreferences.setValue(
777                            PropsKeys.DL_FILE_ENTRY_PREVIEWABLE_PROCESSOR_MAX_SIZE,
778                            String.valueOf(dlFileEntryPreviewableProcessorMaxSize));
779                    portletPreferences.setValue(
780                            PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_HEIGHT,
781                            String.valueOf(dlFileEntryThumbnailMaxHeight));
782                    portletPreferences.setValue(
783                            PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_WIDTH,
784                            String.valueOf(dlFileEntryThumbnailMaxWidth));
785                    portletPreferences.setValue(
786                            PropsKeys.DL_FILE_EXTENSIONS, dlFileExtensions);
787                    portletPreferences.setValue(
788                            PropsKeys.DL_FILE_MAX_SIZE, String.valueOf(dlFileMaxSize));
789                    portletPreferences.setValue(
790                            PropsKeys.JOURNAL_IMAGE_EXTENSIONS, journalImageExtensions);
791                    portletPreferences.setValue(
792                            PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE,
793                            String.valueOf(journalImageSmallMaxSize));
794                    portletPreferences.setValue(
795                            PropsKeys.SHOPPING_IMAGE_EXTENSIONS, shoppingImageExtensions);
796                    portletPreferences.setValue(
797                            PropsKeys.SHOPPING_IMAGE_LARGE_MAX_SIZE,
798                            String.valueOf(shoppingImageLargeMaxSize));
799                    portletPreferences.setValue(
800                            PropsKeys.SHOPPING_IMAGE_MEDIUM_MAX_SIZE,
801                            String.valueOf(shoppingImageMediumMaxSize));
802                    portletPreferences.setValue(
803                            PropsKeys.SHOPPING_IMAGE_SMALL_MAX_SIZE,
804                            String.valueOf(shoppingImageSmallMaxSize));
805                    portletPreferences.setValue(
806                            PropsKeys.SC_IMAGE_MAX_SIZE, String.valueOf(scImageMaxSize));
807                    portletPreferences.setValue(
808                            PropsKeys.SC_IMAGE_THUMBNAIL_MAX_HEIGHT,
809                            String.valueOf(scImageThumbnailMaxHeight));
810                    portletPreferences.setValue(
811                            PropsKeys.SC_IMAGE_THUMBNAIL_MAX_WIDTH,
812                            String.valueOf(scImageThumbnailMaxWidth));
813                    portletPreferences.setValue(
814                            PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE,
815                            String.valueOf(uploadServletRequestImplMaxSize));
816    
817                    if (Validator.isNotNull(uploadServletRequestImplTempDir)) {
818                            portletPreferences.setValue(
819                                    PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_TEMP_DIR,
820                                    uploadServletRequestImplTempDir);
821    
822                            UploadServletRequestImpl.setTempDir(
823                                    new File(uploadServletRequestImplTempDir));
824                    }
825    
826                    portletPreferences.setValue(
827                            PropsKeys.USERS_IMAGE_MAX_SIZE, String.valueOf(usersImageMaxSize));
828    
829                    portletPreferences.store();
830            }
831    
832            protected void updateLogLevels(ActionRequest actionRequest)
833                    throws Exception {
834    
835                    Enumeration<String> enu = actionRequest.getParameterNames();
836    
837                    while (enu.hasMoreElements()) {
838                            String name = enu.nextElement();
839    
840                            if (name.startsWith("logLevel")) {
841                                    String loggerName = name.substring(8);
842    
843                                    String priority = ParamUtil.getString(
844                                            actionRequest, name, Level.INFO.toString());
845    
846                                    Log4JUtil.setLevel(loggerName, priority, true);
847                            }
848                    }
849            }
850    
851            protected void updateMail(
852                            ActionRequest actionRequest, PortletPreferences portletPreferences)
853                    throws Exception {
854    
855                    String advancedProperties = ParamUtil.getString(
856                            actionRequest, "advancedProperties");
857                    String pop3Host = ParamUtil.getString(actionRequest, "pop3Host");
858                    String pop3Password = ParamUtil.getString(
859                            actionRequest, "pop3Password");
860                    int pop3Port = ParamUtil.getInteger(actionRequest, "pop3Port");
861                    boolean pop3Secure = ParamUtil.getBoolean(actionRequest, "pop3Secure");
862                    String pop3User = ParamUtil.getString(actionRequest, "pop3User");
863                    String smtpHost = ParamUtil.getString(actionRequest, "smtpHost");
864                    String smtpPassword = ParamUtil.getString(
865                            actionRequest, "smtpPassword");
866                    int smtpPort = ParamUtil.getInteger(actionRequest, "smtpPort");
867                    boolean smtpSecure = ParamUtil.getBoolean(actionRequest, "smtpSecure");
868                    String smtpUser = ParamUtil.getString(actionRequest, "smtpUser");
869    
870                    String storeProtocol = Account.PROTOCOL_POP;
871    
872                    if (pop3Secure) {
873                            storeProtocol = Account.PROTOCOL_POPS;
874                    }
875    
876                    String transportProtocol = Account.PROTOCOL_SMTP;
877    
878                    if (smtpSecure) {
879                            transportProtocol = Account.PROTOCOL_SMTPS;
880                    }
881    
882                    portletPreferences.setValue(PropsKeys.MAIL_SESSION_MAIL, "true");
883                    portletPreferences.setValue(
884                            PropsKeys.MAIL_SESSION_MAIL_ADVANCED_PROPERTIES,
885                            advancedProperties);
886                    portletPreferences.setValue(
887                            PropsKeys.MAIL_SESSION_MAIL_POP3_HOST, pop3Host);
888    
889                    if (!pop3Password.equals(Portal.TEMP_OBFUSCATION_VALUE)) {
890                            portletPreferences.setValue(
891                                    PropsKeys.MAIL_SESSION_MAIL_POP3_PASSWORD, pop3Password);
892                    }
893    
894                    portletPreferences.setValue(
895                            PropsKeys.MAIL_SESSION_MAIL_POP3_PORT, String.valueOf(pop3Port));
896                    portletPreferences.setValue(
897                            PropsKeys.MAIL_SESSION_MAIL_POP3_USER, pop3User);
898                    portletPreferences.setValue(
899                            PropsKeys.MAIL_SESSION_MAIL_SMTP_HOST, smtpHost);
900    
901                    if (!smtpPassword.equals(Portal.TEMP_OBFUSCATION_VALUE)) {
902                            portletPreferences.setValue(
903                                    PropsKeys.MAIL_SESSION_MAIL_SMTP_PASSWORD, smtpPassword);
904                    }
905    
906                    portletPreferences.setValue(
907                            PropsKeys.MAIL_SESSION_MAIL_SMTP_PORT, String.valueOf(smtpPort));
908                    portletPreferences.setValue(
909                            PropsKeys.MAIL_SESSION_MAIL_SMTP_USER, smtpUser);
910                    portletPreferences.setValue(
911                            PropsKeys.MAIL_SESSION_MAIL_STORE_PROTOCOL, storeProtocol);
912                    portletPreferences.setValue(
913                            PropsKeys.MAIL_SESSION_MAIL_TRANSPORT_PROTOCOL, transportProtocol);
914    
915                    portletPreferences.store();
916    
917                    MailServiceUtil.clearSession();
918            }
919    
920            protected void validateCaptcha(ActionRequest actionRequest)
921                    throws Exception {
922    
923                    boolean reCaptchaEnabled = ParamUtil.getBoolean(
924                            actionRequest, "reCaptchaEnabled");
925    
926                    if (!reCaptchaEnabled) {
927                            return;
928                    }
929    
930                    String reCaptchaPrivateKey = ParamUtil.getString(
931                            actionRequest, "reCaptchaPrivateKey");
932                    String reCaptchaPublicKey = ParamUtil.getString(
933                            actionRequest, "reCaptchaPublicKey");
934    
935                    if (Validator.isNull(reCaptchaPublicKey)) {
936                            SessionErrors.add(actionRequest, "reCaptchaPublicKey");
937                    }
938                    else if (Validator.isNull(reCaptchaPrivateKey)) {
939                            SessionErrors.add(actionRequest, "reCaptchaPrivateKey");
940                    }
941            }
942    
943            protected void verifyMembershipPolicies() throws Exception {
944                    OrganizationMembershipPolicy organizationMembershipPolicy =
945                            OrganizationMembershipPolicyFactoryUtil.
946                                    getOrganizationMembershipPolicy();
947    
948                    organizationMembershipPolicy.verifyPolicy();
949    
950                    RoleMembershipPolicy roleMembershipPolicy =
951                            RoleMembershipPolicyFactoryUtil.getRoleMembershipPolicy();
952    
953                    roleMembershipPolicy.verifyPolicy();
954    
955                    SiteMembershipPolicy siteMembershipPolicy =
956                            SiteMembershipPolicyFactoryUtil.getSiteMembershipPolicy();
957    
958                    siteMembershipPolicy.verifyPolicy();
959    
960                    UserGroupMembershipPolicy userGroupMembershipPolicy =
961                            UserGroupMembershipPolicyFactoryUtil.getUserGroupMembershipPolicy();
962    
963                    userGroupMembershipPolicy.verifyPolicy();
964            }
965    
966            protected void verifyPluginTables() throws Exception {
967                    ServiceComponentLocalServiceUtil.verifyDB();
968            }
969    
970            private static Log _log = LogFactoryUtil.getLog(EditServerAction.class);
971    
972            private static MethodKey _loadIndexesFromClusterMethodKey = new MethodKey(
973                    LuceneClusterUtil.class, "loadIndexesFromCluster", long[].class,
974                    Address.class);
975    
976            private static class ClusterLoadingSyncJob implements Runnable {
977    
978                    public ClusterLoadingSyncJob(
979                            long[] companyIds, CountDownLatch countDownLatch, boolean master) {
980    
981                            _companyIds = companyIds;
982                            _countDownLatch = countDownLatch;
983                            _master = master;
984                    }
985    
986                    @Override
987                    public void run() {
988                            _countDownLatch.countDown();
989    
990                            String logPrefix = StringPool.BLANK;
991    
992                            if (_log.isInfoEnabled()) {
993                                    Thread currentThread = Thread.currentThread();
994    
995                                    if (_master) {
996                                            logPrefix =
997                                                    "Monitor thread name " + currentThread.getName() +
998                                                            " with thread ID " + currentThread.getId();
999                                    }
1000                                    else {
1001                                            logPrefix =
1002                                                    "Thread name " + currentThread.getName() +
1003                                                            " with thread ID " + currentThread.getId();
1004                                    }
1005                            }
1006    
1007                            if (!_master && _log.isInfoEnabled()) {
1008                                    _log.info(
1009                                            logPrefix + " synchronized on latch. Waiting for others.");
1010                            }
1011    
1012                            try {
1013                                    if (_master) {
1014                                            _countDownLatch.await();
1015                                    }
1016                                    else {
1017                                            boolean result = _countDownLatch.await(
1018                                                    PropsValues.LUCENE_CLUSTER_INDEX_LOADING_SYNC_TIMEOUT,
1019                                                    TimeUnit.MILLISECONDS);
1020    
1021                                            if (!result) {
1022                                                    _log.error(
1023                                                            logPrefix + " timed out. You may need to " +
1024                                                                    "re-trigger a reindex process.");
1025                                            }
1026                                    }
1027                            }
1028                            catch (InterruptedException ie) {
1029                                    if (_master) {
1030                                            _log.error(
1031                                                    logPrefix + " was interrupted. Skip cluster index " +
1032                                                            "loading notification.",
1033                                                    ie);
1034    
1035                                            return;
1036                                    }
1037                                    else {
1038                                            _log.error(
1039                                                    logPrefix + " was interrupted. You may need to " +
1040                                                            "re-trigger a reindex process.",
1041                                                    ie);
1042                                    }
1043                            }
1044    
1045                            if (_master) {
1046                                    Address localClusterNodeAddress =
1047                                            ClusterExecutorUtil.getLocalClusterNodeAddress();
1048    
1049                                    ClusterRequest clusterRequest =
1050                                            ClusterRequest.createMulticastRequest(
1051                                                    new MethodHandler(
1052                                                            _loadIndexesFromClusterMethodKey, _companyIds,
1053                                                            localClusterNodeAddress),
1054                                                    true);
1055    
1056                                    try {
1057                                            ClusterExecutorUtil.execute(clusterRequest);
1058                                    }
1059                                    catch (SystemException se) {
1060                                            _log.error(
1061                                                    "Unable to notify peers to start index loading", se);
1062                                    }
1063    
1064                                    if (_log.isInfoEnabled()) {
1065                                            _log.info(
1066                                                    logPrefix + " unlocked latch. Notified peers to " +
1067                                                            "start index loading.");
1068                                    }
1069                            }
1070                    }
1071    
1072                    private long[] _companyIds;
1073                    private CountDownLatch _countDownLatch;
1074                    private boolean _master;
1075    
1076            }
1077    
1078    }