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