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