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