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