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                                            finally {
421                                                    ShardUtil.popCompanyService();
422                                            }
423                                    }
424                            }
425                    }
426    
427                    if (LuceneHelperUtil.isLoadIndexFromClusterEnabled()) {
428                            Set<BaseAsyncDestination> searchWriterDestinations =
429                                    new HashSet<BaseAsyncDestination>();
430    
431                            MessageBus messageBus = MessageBusUtil.getMessageBus();
432    
433                            for (String usedSearchEngineId : usedSearchEngineIds) {
434                                    String searchWriterDestinationName =
435                                            SearchEngineUtil.getSearchWriterDestinationName(
436                                                    usedSearchEngineId);
437    
438                                    Destination destination = messageBus.getDestination(
439                                            searchWriterDestinationName);
440    
441                                    if (destination instanceof BaseAsyncDestination) {
442                                            BaseAsyncDestination baseAsyncDestination =
443                                                    (BaseAsyncDestination)destination;
444    
445                                            searchWriterDestinations.add(baseAsyncDestination);
446                                    }
447                            }
448    
449                            submitClusterIndexLoadingSyncJob(
450                                    searchWriterDestinations, companyIds);
451                    }
452            }
453    
454            protected void runScript(
455                            PortletConfig portletConfig, ActionRequest actionRequest,
456                            ActionResponse actionResponse)
457                    throws Exception {
458    
459                    String language = ParamUtil.getString(actionRequest, "language");
460                    String script = ParamUtil.getString(actionRequest, "script");
461    
462                    PortletContext portletContext = portletConfig.getPortletContext();
463    
464                    Map<String, Object> portletObjects = ScriptingUtil.getPortletObjects(
465                            portletConfig, portletContext, actionRequest, actionResponse);
466    
467                    UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
468                            new UnsyncByteArrayOutputStream();
469    
470                    UnsyncPrintWriter unsyncPrintWriter = UnsyncPrintWriterPool.borrow(
471                            unsyncByteArrayOutputStream);
472    
473                    portletObjects.put("out", unsyncPrintWriter);
474    
475                    try {
476                            SessionMessages.add(actionRequest, "language", language);
477                            SessionMessages.add(actionRequest, "script", script);
478    
479                            ScriptingUtil.exec(null, portletObjects, language, script);
480    
481                            unsyncPrintWriter.flush();
482    
483                            SessionMessages.add(
484                                    actionRequest, "scriptOutput",
485                                    unsyncByteArrayOutputStream.toString());
486                    }
487                    catch (ScriptingException se) {
488                            SessionErrors.add(
489                                    actionRequest, ScriptingException.class.getName(), se);
490    
491                            _log.error(se.getMessage());
492                    }
493            }
494    
495            protected void shutdown(ActionRequest actionRequest) throws Exception {
496                    long minutes =
497                            ParamUtil.getInteger(actionRequest, "minutes") * Time.MINUTE;
498                    String message = ParamUtil.getString(actionRequest, "message");
499    
500                    if (minutes <= 0) {
501                            ShutdownUtil.cancel();
502                    }
503                    else {
504                            ShutdownUtil.shutdown(minutes, message);
505                    }
506            }
507    
508            protected void submitClusterIndexLoadingSyncJob(
509                            Set<BaseAsyncDestination> baseAsyncDestinations, long[] companyIds)
510                    throws Exception {
511    
512                    if (_log.isInfoEnabled()) {
513                            StringBundler sb = new StringBundler(
514                                    baseAsyncDestinations.size() + 1);
515    
516                            sb.append("[");
517    
518                            for (BaseAsyncDestination baseAsyncDestination :
519                                            baseAsyncDestinations) {
520    
521                                    sb.append(baseAsyncDestination.getName());
522                                    sb.append(", ");
523                            }
524    
525                            sb.setStringAt("]", sb.index() - 1);
526    
527                            _log.info(
528                                    "Synchronizecluster index loading for destinations " +
529                                            sb.toString());
530                    }
531    
532                    int totalWorkersMaxSize = 0;
533    
534                    for (BaseAsyncDestination baseAsyncDestination :
535                                    baseAsyncDestinations) {
536    
537                            totalWorkersMaxSize += baseAsyncDestination.getWorkersMaxSize();
538                    }
539    
540                    if (_log.isInfoEnabled()) {
541                            _log.info(
542                                    "There are " + totalWorkersMaxSize +
543                                            " synchronization threads");
544                    }
545    
546                    CountDownLatch countDownLatch = new CountDownLatch(
547                            totalWorkersMaxSize + 1);
548    
549                    ClusterLoadingSyncJob slaveClusterLoadingSyncJob =
550                            new ClusterLoadingSyncJob(companyIds, countDownLatch, false);
551    
552                    for (BaseAsyncDestination baseAsyncDestination :
553                                    baseAsyncDestinations) {
554    
555                            ThreadPoolExecutor threadPoolExecutor =
556                                    PortalExecutorManagerUtil.getPortalExecutor(
557                                            baseAsyncDestination.getName());
558    
559                            for (int i = 0; i < baseAsyncDestination.getWorkersMaxSize(); i++) {
560                                    threadPoolExecutor.execute(slaveClusterLoadingSyncJob);
561                            }
562                    }
563    
564                    ClusterLoadingSyncJob masterClusterLoadingSyncJob =
565                            new ClusterLoadingSyncJob(companyIds, countDownLatch, true);
566    
567                    ThreadPoolExecutor threadPoolExecutor =
568                            PortalExecutorManagerUtil.getPortalExecutor(
569                                    EditServerAction.class.getName());
570    
571                    threadPoolExecutor.execute(masterClusterLoadingSyncJob);
572            }
573    
574            protected void threadDump() throws Exception {
575                    if (_log.isInfoEnabled()) {
576                            _log.info(ThreadUtil.threadDump());
577                    }
578                    else {
579                            _log.error(
580                                    "Thread dumps require the log level to be at least INFO for " +
581                                            getClass().getName());
582                    }
583            }
584    
585            protected void updateCaptcha(
586                            ActionRequest actionRequest, PortletPreferences preferences)
587                    throws Exception {
588    
589                    boolean reCaptchaEnabled = ParamUtil.getBoolean(
590                            actionRequest, "reCaptchaEnabled");
591                    String reCaptchaPrivateKey = ParamUtil.getString(
592                            actionRequest, "reCaptchaPrivateKey");
593                    String reCaptchaPublicKey = ParamUtil.getString(
594                            actionRequest, "reCaptchaPublicKey");
595    
596                    Captcha captcha = null;
597    
598                    if (reCaptchaEnabled) {
599                            captcha = new ReCaptchaImpl();
600                    }
601                    else {
602                            captcha = new SimpleCaptchaImpl();
603                    }
604    
605                    validateCaptcha(actionRequest);
606    
607                    if (SessionErrors.isEmpty(actionRequest)) {
608                            preferences.setValue(
609                                    PropsKeys.CAPTCHA_ENGINE_IMPL, captcha.getClass().getName());
610                            preferences.setValue(
611                                    PropsKeys.CAPTCHA_ENGINE_RECAPTCHA_KEY_PRIVATE,
612                                    reCaptchaPrivateKey);
613                            preferences.setValue(
614                                    PropsKeys.CAPTCHA_ENGINE_RECAPTCHA_KEY_PUBLIC,
615                                    reCaptchaPublicKey);
616    
617                            preferences.store();
618    
619                            CaptchaImpl captchaImpl = (CaptchaImpl)CaptchaUtil.getCaptcha();
620    
621                            captchaImpl.setCaptcha(captcha);
622                    }
623            }
624    
625            protected void updateExternalServices(
626                            ActionRequest actionRequest, PortletPreferences preferences)
627                    throws Exception {
628    
629                    boolean imageMagickEnabled = ParamUtil.getBoolean(
630                            actionRequest, "imageMagickEnabled");
631                    String imageMagickPath = ParamUtil.getString(
632                            actionRequest, "imageMagickPath");
633                    boolean openOfficeEnabled = ParamUtil.getBoolean(
634                            actionRequest, "openOfficeEnabled");
635                    int openOfficePort = ParamUtil.getInteger(
636                            actionRequest, "openOfficePort");
637                    boolean xugglerEnabled = ParamUtil.getBoolean(
638                            actionRequest, "xugglerEnabled");
639    
640                    preferences.setValue(
641                            PropsKeys.IMAGEMAGICK_ENABLED, String.valueOf(imageMagickEnabled));
642                    preferences.setValue(
643                            PropsKeys.IMAGEMAGICK_GLOBAL_SEARCH_PATH, imageMagickPath);
644                    preferences.setValue(
645                            PropsKeys.OPENOFFICE_SERVER_ENABLED,
646                            String.valueOf(openOfficeEnabled));
647                    preferences.setValue(
648                            PropsKeys.OPENOFFICE_SERVER_PORT, String.valueOf(openOfficePort));
649                    preferences.setValue(
650                            PropsKeys.XUGGLER_ENABLED, String.valueOf(xugglerEnabled));
651    
652                    Enumeration<String> enu = actionRequest.getParameterNames();
653    
654                    while (enu.hasMoreElements()) {
655                            String name = enu.nextElement();
656    
657                            if (name.startsWith("imageMagickLimit")) {
658                                    String key = name.substring(16, name.length()).toLowerCase();
659                                    String value = ParamUtil.getString(actionRequest, name);
660    
661                                    preferences.setValue(
662                                            PropsKeys.IMAGEMAGICK_RESOURCE_LIMIT + key, value);
663                            }
664                    }
665    
666                    preferences.store();
667    
668                    GhostscriptUtil.reset();
669                    ImageMagickUtil.reset();
670            }
671    
672            protected void updateFileUploads(
673                            ActionRequest actionRequest, PortletPreferences preferences)
674                    throws Exception {
675    
676                    long dlFileEntryThumbnailMaxHeight = ParamUtil.getLong(
677                            actionRequest, "dlFileEntryThumbnailMaxHeight");
678                    long dlFileEntryThumbnailMaxWidth = ParamUtil.getLong(
679                            actionRequest, "dlFileEntryThumbnailMaxWidth");
680                    String dlFileExtensions = getFileExtensions(
681                            actionRequest, "dlFileExtensions");
682                    long dlFileMaxSize = ParamUtil.getLong(actionRequest, "dlFileMaxSize");
683                    String journalImageExtensions = getFileExtensions(
684                            actionRequest, "journalImageExtensions");
685                    long journalImageSmallMaxSize = ParamUtil.getLong(
686                            actionRequest, "journalImageSmallMaxSize");
687                    String shoppingImageExtensions = getFileExtensions(
688                            actionRequest, "shoppingImageExtensions");
689                    long scImageMaxSize = ParamUtil.getLong(
690                            actionRequest, "scImageMaxSize");
691                    long scImageThumbnailMaxHeight = ParamUtil.getLong(
692                            actionRequest, "scImageThumbnailMaxHeight");
693                    long scImageThumbnailMaxWidth = ParamUtil.getLong(
694                            actionRequest, "scImageThumbnailMaxWidth");
695                    long shoppingImageLargeMaxSize = ParamUtil.getLong(
696                            actionRequest, "shoppingImageLargeMaxSize");
697                    long shoppingImageMediumMaxSize = ParamUtil.getLong(
698                            actionRequest, "shoppingImageMediumMaxSize");
699                    long shoppingImageSmallMaxSize = ParamUtil.getLong(
700                            actionRequest, "shoppingImageSmallMaxSize");
701                    long uploadServletRequestImplMaxSize = ParamUtil.getLong(
702                            actionRequest, "uploadServletRequestImplMaxSize");
703                    String uploadServletRequestImplTempDir = ParamUtil.getString(
704                            actionRequest, "uploadServletRequestImplTempDir");
705                    long usersImageMaxSize = ParamUtil.getLong(
706                            actionRequest, "usersImageMaxSize");
707    
708                    preferences.setValue(
709                            PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_HEIGHT,
710                            String.valueOf(dlFileEntryThumbnailMaxHeight));
711                    preferences.setValue(
712                            PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_WIDTH,
713                            String.valueOf(dlFileEntryThumbnailMaxWidth));
714                    preferences.setValue(PropsKeys.DL_FILE_EXTENSIONS, dlFileExtensions);
715                    preferences.setValue(
716                            PropsKeys.DL_FILE_MAX_SIZE, String.valueOf(dlFileMaxSize));
717                    preferences.setValue(
718                            PropsKeys.JOURNAL_IMAGE_EXTENSIONS, journalImageExtensions);
719                    preferences.setValue(
720                            PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE,
721                            String.valueOf(journalImageSmallMaxSize));
722                    preferences.setValue(
723                            PropsKeys.SHOPPING_IMAGE_EXTENSIONS, shoppingImageExtensions);
724                    preferences.setValue(
725                            PropsKeys.SHOPPING_IMAGE_LARGE_MAX_SIZE,
726                            String.valueOf(shoppingImageLargeMaxSize));
727                    preferences.setValue(
728                            PropsKeys.SHOPPING_IMAGE_MEDIUM_MAX_SIZE,
729                            String.valueOf(shoppingImageMediumMaxSize));
730                    preferences.setValue(
731                            PropsKeys.SHOPPING_IMAGE_SMALL_MAX_SIZE,
732                            String.valueOf(shoppingImageSmallMaxSize));
733                    preferences.setValue(
734                            PropsKeys.SC_IMAGE_MAX_SIZE, String.valueOf(scImageMaxSize));
735                    preferences.setValue(
736                            PropsKeys.SC_IMAGE_THUMBNAIL_MAX_HEIGHT,
737                            String.valueOf(scImageThumbnailMaxHeight));
738                    preferences.setValue(
739                            PropsKeys.SC_IMAGE_THUMBNAIL_MAX_WIDTH,
740                            String.valueOf(scImageThumbnailMaxWidth));
741                    preferences.setValue(
742                            PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE,
743                            String.valueOf(uploadServletRequestImplMaxSize));
744    
745                    if (Validator.isNotNull(uploadServletRequestImplTempDir)) {
746                            preferences.setValue(
747                                    PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_TEMP_DIR,
748                                    uploadServletRequestImplTempDir);
749    
750                            UploadServletRequestImpl.setTempDir(
751                                    new File(uploadServletRequestImplTempDir));
752                    }
753    
754                    preferences.setValue(
755                            PropsKeys.USERS_IMAGE_MAX_SIZE, String.valueOf(usersImageMaxSize));
756    
757                    preferences.store();
758            }
759    
760            protected void updateLogLevels(ActionRequest actionRequest)
761                    throws Exception {
762    
763                    Enumeration<String> enu = actionRequest.getParameterNames();
764    
765                    while (enu.hasMoreElements()) {
766                            String name = enu.nextElement();
767    
768                            if (name.startsWith("logLevel")) {
769                                    String loggerName = name.substring(8);
770    
771                                    String priority = ParamUtil.getString(
772                                            actionRequest, name, Level.INFO.toString());
773    
774                                    Log4JUtil.setLevel(loggerName, priority, true);
775                            }
776                    }
777            }
778    
779            protected void updateMail(
780                            ActionRequest actionRequest, PortletPreferences preferences)
781                    throws Exception {
782    
783                    String advancedProperties = ParamUtil.getString(
784                            actionRequest, "advancedProperties");
785                    String pop3Host = ParamUtil.getString(actionRequest, "pop3Host");
786                    String pop3Password = ParamUtil.getString(
787                            actionRequest, "pop3Password");
788                    int pop3Port = ParamUtil.getInteger(actionRequest, "pop3Port");
789                    boolean pop3Secure = ParamUtil.getBoolean(actionRequest, "pop3Secure");
790                    String pop3User = ParamUtil.getString(actionRequest, "pop3User");
791                    String smtpHost = ParamUtil.getString(actionRequest, "smtpHost");
792                    String smtpPassword = ParamUtil.getString(
793                            actionRequest, "smtpPassword");
794                    int smtpPort = ParamUtil.getInteger(actionRequest, "smtpPort");
795                    boolean smtpSecure = ParamUtil.getBoolean(actionRequest, "smtpSecure");
796                    String smtpUser = ParamUtil.getString(actionRequest, "smtpUser");
797    
798                    String storeProtocol = Account.PROTOCOL_POP;
799    
800                    if (pop3Secure) {
801                            storeProtocol = Account.PROTOCOL_POPS;
802                    }
803    
804                    String transportProtocol = Account.PROTOCOL_SMTP;
805    
806                    if (smtpSecure) {
807                            transportProtocol = Account.PROTOCOL_SMTPS;
808                    }
809    
810                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL, "true");
811                    preferences.setValue(
812                            PropsKeys.MAIL_SESSION_MAIL_ADVANCED_PROPERTIES,
813                            advancedProperties);
814                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_POP3_HOST, pop3Host);
815                    preferences.setValue(
816                            PropsKeys.MAIL_SESSION_MAIL_POP3_PASSWORD, pop3Password);
817                    preferences.setValue(
818                            PropsKeys.MAIL_SESSION_MAIL_POP3_PORT, String.valueOf(pop3Port));
819                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_POP3_USER, pop3User);
820                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_SMTP_HOST, smtpHost);
821                    preferences.setValue(
822                            PropsKeys.MAIL_SESSION_MAIL_SMTP_PASSWORD, smtpPassword);
823                    preferences.setValue(
824                            PropsKeys.MAIL_SESSION_MAIL_SMTP_PORT, String.valueOf(smtpPort));
825                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_SMTP_USER, smtpUser);
826                    preferences.setValue(
827                            PropsKeys.MAIL_SESSION_MAIL_STORE_PROTOCOL, storeProtocol);
828                    preferences.setValue(
829                            PropsKeys.MAIL_SESSION_MAIL_TRANSPORT_PROTOCOL, transportProtocol);
830    
831                    preferences.store();
832    
833                    MailServiceUtil.clearSession();
834            }
835    
836            protected void validateCaptcha(ActionRequest actionRequest)
837                    throws Exception {
838    
839                    boolean reCaptchaEnabled = ParamUtil.getBoolean(
840                            actionRequest, "reCaptchaEnabled");
841    
842                    if (!reCaptchaEnabled) {
843                            return;
844                    }
845    
846                    String reCaptchaPrivateKey = ParamUtil.getString(
847                            actionRequest, "reCaptchaPrivateKey");
848                    String reCaptchaPublicKey = ParamUtil.getString(
849                            actionRequest, "reCaptchaPublicKey");
850    
851                    if (Validator.isNull(reCaptchaPublicKey)) {
852                            SessionErrors.add(actionRequest, "reCaptchaPublicKey");
853                    }
854                    else if (Validator.isNull(reCaptchaPrivateKey)) {
855                            SessionErrors.add(actionRequest, "reCaptchaPrivateKey");
856                    }
857            }
858    
859            protected void verifyPluginTables() throws Exception {
860                    ServiceComponentLocalServiceUtil.verifyDB();
861            }
862    
863            private static Log _log = LogFactoryUtil.getLog(EditServerAction.class);
864    
865            private static MethodKey _loadIndexesFromClusterMethodKey = new MethodKey(
866                    LuceneClusterUtil.class, "loadIndexesFromCluster", long[].class,
867                    Address.class);
868    
869            private static class ClusterLoadingSyncJob implements Runnable {
870    
871                    public ClusterLoadingSyncJob(
872                            long[] companyIds, CountDownLatch countDownLatch, boolean master) {
873    
874                            _companyIds = companyIds;
875                            _countDownLatch = countDownLatch;
876                            _master = master;
877                    }
878    
879                    public void run() {
880                            _countDownLatch.countDown();
881    
882                            String logPrefix = StringPool.BLANK;
883    
884                            if (_log.isInfoEnabled()) {
885                                    Thread currentThread = Thread.currentThread();
886    
887                                    if (_master) {
888                                            logPrefix =
889                                                    "Monitor thread name " + currentThread.getName() +
890                                                            " with thread ID " + currentThread.getId();
891                                    }
892                                    else {
893                                            logPrefix =
894                                                    "Thread name " + currentThread.getName() +
895                                                            " with thread ID " + currentThread.getId();
896                                    }
897                            }
898    
899                            if (!_master && _log.isInfoEnabled()) {
900                                    _log.info(
901                                            logPrefix + " synchronized on latch. Waiting for others.");
902                            }
903    
904                            try {
905                                    if (_master) {
906                                            _countDownLatch.await();
907                                    }
908                                    else {
909                                            boolean result = _countDownLatch.await(
910                                                    PropsValues.LUCENE_CLUSTER_INDEX_LOADING_SYNC_TIMEOUT,
911                                                    TimeUnit.MILLISECONDS);
912    
913                                            if (!result) {
914                                                    _log.error(
915                                                            logPrefix + " timed out. You may need to " +
916                                                                    "re-trigger a reindex process.");
917                                            }
918                                    }
919                            }
920                            catch (InterruptedException ie) {
921                                    if (_master) {
922                                            _log.error(
923                                                    logPrefix + " was interrupted. Skip cluster index " +
924                                                            "loading notification.",
925                                                    ie);
926    
927                                            return;
928                                    }
929                                    else {
930                                            _log.error(
931                                                    logPrefix + " was interrupted. You may need to " +
932                                                            "re-trigger a reindex process.",
933                                                    ie);
934                                    }
935                            }
936    
937                            if (_master) {
938                                    Address localClusterNodeAddress =
939                                            ClusterExecutorUtil.getLocalClusterNodeAddress();
940    
941                                    ClusterRequest clusterRequest =
942                                            ClusterRequest.createMulticastRequest(
943                                                    new MethodHandler(
944                                                            _loadIndexesFromClusterMethodKey, _companyIds,
945                                                            localClusterNodeAddress),
946                                                    true);
947    
948                                    try {
949                                            ClusterExecutorUtil.execute(clusterRequest);
950                                    }
951                                    catch (SystemException se) {
952                                            _log.error(
953                                                    "Unable to notify peers to start index loading", se);
954                                    }
955    
956                                    if (_log.isInfoEnabled()) {
957                                            _log.info(
958                                                    logPrefix + " unlocked latch. Notified peers to " +
959                                                            "start index loading.");
960                                    }
961                            }
962                    }
963    
964                    private long[] _companyIds;
965                    private CountDownLatch _countDownLatch;
966                    private boolean _master;
967    
968            }
969    
970    }