001    /**
002     * Copyright (c) 2000-2010 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.convert.ConvertProcess;
019    import com.liferay.portal.kernel.cache.CacheRegistryUtil;
020    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
021    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.mail.Account;
025    import com.liferay.portal.kernel.messaging.DestinationNames;
026    import com.liferay.portal.kernel.messaging.MessageBusUtil;
027    import com.liferay.portal.kernel.scripting.ScriptingException;
028    import com.liferay.portal.kernel.scripting.ScriptingUtil;
029    import com.liferay.portal.kernel.search.Indexer;
030    import com.liferay.portal.kernel.search.SearchEngineUtil;
031    import com.liferay.portal.kernel.servlet.SessionErrors;
032    import com.liferay.portal.kernel.servlet.SessionMessages;
033    import com.liferay.portal.kernel.util.Constants;
034    import com.liferay.portal.kernel.util.InstancePool;
035    import com.liferay.portal.kernel.util.ParamUtil;
036    import com.liferay.portal.kernel.util.PropsKeys;
037    import com.liferay.portal.kernel.util.StringBundler;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.StringUtil;
040    import com.liferay.portal.kernel.util.Time;
041    import com.liferay.portal.kernel.util.Validator;
042    import com.liferay.portal.kernel.webcache.WebCachePoolUtil;
043    import com.liferay.portal.model.Portlet;
044    import com.liferay.portal.search.lucene.LuceneIndexer;
045    import com.liferay.portal.security.auth.PrincipalException;
046    import com.liferay.portal.security.permission.PermissionChecker;
047    import com.liferay.portal.service.PortletLocalServiceUtil;
048    import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
049    import com.liferay.portal.struts.PortletAction;
050    import com.liferay.portal.theme.ThemeDisplay;
051    import com.liferay.portal.util.MaintenanceUtil;
052    import com.liferay.portal.util.PortalInstances;
053    import com.liferay.portal.util.PrefsPropsUtil;
054    import com.liferay.portal.util.ShutdownUtil;
055    import com.liferay.portal.util.WebKeys;
056    import com.liferay.portlet.ActionResponseImpl;
057    import com.liferay.util.log4j.Log4JUtil;
058    
059    import java.util.Enumeration;
060    import java.util.Map;
061    
062    import javax.portlet.ActionRequest;
063    import javax.portlet.ActionResponse;
064    import javax.portlet.PortletConfig;
065    import javax.portlet.PortletContext;
066    import javax.portlet.PortletPreferences;
067    import javax.portlet.PortletSession;
068    import javax.portlet.PortletURL;
069    import javax.portlet.WindowState;
070    
071    import org.apache.log4j.Level;
072    import org.apache.log4j.Logger;
073    import org.apache.struts.action.ActionForm;
074    import org.apache.struts.action.ActionMapping;
075    
076    /**
077     * @author Brian Wing Shun Chan
078     */
079    public class EditServerAction extends PortletAction {
080    
081            public void processAction(
082                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
083                            ActionRequest actionRequest, ActionResponse actionResponse)
084                    throws Exception {
085    
086                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
087                            WebKeys.THEME_DISPLAY);
088    
089                    PermissionChecker permissionChecker =
090                            themeDisplay.getPermissionChecker();
091    
092                    if (!permissionChecker.isOmniadmin()) {
093                            SessionErrors.add(
094                                    actionRequest, PrincipalException.class.getName());
095    
096                            setForward(actionRequest, "portlet.admin.error");
097    
098                            return;
099                    }
100    
101                    PortletPreferences preferences = PrefsPropsUtil.getPreferences();
102    
103                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
104    
105                    String redirect = null;
106    
107                    if (cmd.equals("addLogLevel")) {
108                            addLogLevel(actionRequest);
109                    }
110                    else if (cmd.equals("cacheDb")) {
111                            cacheDb();
112                    }
113                    else if (cmd.equals("cacheMulti")) {
114                            cacheMulti();
115                    }
116                    else if (cmd.equals("cacheSingle")) {
117                            cacheSingle();
118                    }
119                    else if (cmd.startsWith("convertProcess.")) {
120                            redirect = convertProcess(actionRequest, actionResponse, cmd);
121                    }
122                    else if (cmd.equals("gc")) {
123                            gc();
124                    }
125                    else if (cmd.equals("reindex")) {
126                            reindex(actionRequest);
127                    }
128                    else if (cmd.equals("runScript")) {
129                            runScript(portletConfig, actionRequest, actionResponse);
130                    }
131                    else if (cmd.equals("shutdown")) {
132                            shutdown(actionRequest);
133                    }
134                    else if (cmd.equals("threadDump")) {
135                            threadDump();
136                    }
137                    else if (cmd.equals("updateFileUploads")) {
138                            updateFileUploads(actionRequest, preferences);
139                    }
140                    else if (cmd.equals("updateLogLevels")) {
141                            updateLogLevels(actionRequest);
142                    }
143                    else if (cmd.equals("updateMail")) {
144                            updateMail(actionRequest, preferences);
145                    }
146                    else if (cmd.equals("updateOpenOffice")) {
147                            updateOpenOffice(actionRequest, preferences);
148                    }
149                    else if (cmd.equals("verifyPluginTables")) {
150                            verifyPluginTables();
151                    }
152    
153                    sendRedirect(actionRequest, actionResponse, redirect);
154            }
155    
156            protected void addLogLevel(ActionRequest actionRequest) throws Exception {
157                    String loggerName = ParamUtil.getString(actionRequest, "loggerName");
158                    String priority = ParamUtil.getString(actionRequest, "priority");
159    
160                    Logger logger = Logger.getLogger(loggerName);
161    
162                    logger.setLevel(Level.toLevel(priority));
163            }
164    
165            protected void cacheDb() throws Exception {
166                    CacheRegistryUtil.clear();
167            }
168    
169            protected void cacheMulti() throws Exception {
170                    MultiVMPoolUtil.clear();
171            }
172    
173            protected void cacheSingle() throws Exception {
174                    WebCachePoolUtil.clear();
175            }
176    
177            protected String convertProcess(
178                            ActionRequest actionRequest, ActionResponse actionResponse,
179                            String cmd)
180                    throws Exception {
181    
182                    ActionResponseImpl actionResponseImpl =
183                            (ActionResponseImpl)actionResponse;
184    
185                    PortletSession portletSession = actionRequest.getPortletSession();
186    
187                    String className = StringUtil.replaceFirst(
188                            cmd, "convertProcess.", StringPool.BLANK);
189    
190                    ConvertProcess convertProcess = (ConvertProcess)InstancePool.get(
191                            className);
192    
193                    String[] parameters = convertProcess.getParameterNames();
194    
195                    if (parameters != null) {
196                            String[] values = new String[parameters.length];
197    
198                            for (int i = 0; i < parameters.length; i++) {
199                                    String parameter =
200                                            className + StringPool.PERIOD + parameters[i];
201    
202                                    if (parameters[i].contains(StringPool.EQUAL)) {
203                                            String[] parameterPair = StringUtil.split(
204                                                    parameters[i], StringPool.EQUAL);
205    
206                                            parameter =
207                                                    className + StringPool.PERIOD + parameterPair[0];
208                                    }
209    
210                                    values[i] = ParamUtil.getString(actionRequest, parameter);
211                            }
212    
213                            convertProcess.setParameterValues(values);
214                    }
215    
216                    String path = convertProcess.getPath();
217    
218                    if (path != null) {
219                            PortletURL portletURL = actionResponseImpl.createRenderURL();
220    
221                            portletURL.setWindowState(WindowState.MAXIMIZED);
222    
223                            portletURL.setParameter("struts_action", path);
224    
225                            return portletURL.toString();
226                    }
227                    else {
228                            MaintenanceUtil.maintain(portletSession.getId(), className);
229    
230                            MessageBusUtil.sendMessage(
231                                    DestinationNames.CONVERT_PROCESS, className);
232    
233                            return null;
234                    }
235            }
236    
237            protected void gc() throws Exception {
238                    Runtime.getRuntime().gc();
239            }
240    
241            protected String getFileExtensions(
242                    ActionRequest actionRequest, String name) {
243    
244                    String value = ParamUtil.getString(actionRequest, name);
245    
246                    return value.replace(", .", ",.");
247            }
248    
249            protected void reindex(ActionRequest actionRequest) throws Exception {
250                    String portletId = ParamUtil.getString(actionRequest, "portletId");
251    
252                    long[] companyIds = PortalInstances.getCompanyIds();
253    
254                    if (Validator.isNull(portletId)) {
255                            for (long companyId : companyIds) {
256                                    try {
257                                            LuceneIndexer indexer = new LuceneIndexer(companyId);
258    
259                                            indexer.reindex();
260                                    }
261                                    catch (Exception e) {
262                                            _log.error(e, e);
263                                    }
264                            }
265                    }
266                    else {
267                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
268                                    companyIds[0], portletId);
269    
270                            if (portlet == null) {
271                                    return;
272                            }
273    
274                            Indexer indexer = portlet.getIndexerInstance();
275    
276                            if (indexer == null) {
277                                    return;
278                            }
279    
280                            for (long companyId : companyIds) {
281                                    try {
282                                            SearchEngineUtil.deletePortletDocuments(
283                                                    companyId, portletId);
284    
285                                            indexer.reindex(new String[] {String.valueOf(companyId)});
286                                    }
287                                    catch (Exception e) {
288                                            _log.error(e, e);
289                                    }
290                            }
291                    }
292            }
293    
294            protected void runScript(
295                            PortletConfig portletConfig, ActionRequest actionRequest,
296                            ActionResponse actionResponse)
297                    throws Exception {
298    
299                    String language = ParamUtil.getString(actionRequest, "language");
300                    String script = ParamUtil.getString(actionRequest, "script");
301    
302                    PortletContext portletContext = portletConfig.getPortletContext();
303    
304                    Map<String, Object> portletObjects = ScriptingUtil.getPortletObjects(
305                            portletConfig, portletContext, actionRequest, actionResponse);
306    
307                    UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
308                            new UnsyncByteArrayOutputStream();
309    
310                    portletObjects.put("out", unsyncByteArrayOutputStream);
311    
312                    try {
313                            ScriptingUtil.exec(null, portletObjects, language, script);
314    
315                            SessionMessages.add(
316                                    actionRequest, "script_output",
317                                    unsyncByteArrayOutputStream.toString());
318                    }
319                    catch (ScriptingException se) {
320                            SessionErrors.add(
321                                    actionRequest, ScriptingException.class.getName(), se);
322    
323                            _log.error(se.getMessage());
324                    }
325            }
326    
327            protected void shutdown(ActionRequest actionRequest) throws Exception {
328                    long minutes =
329                            ParamUtil.getInteger(actionRequest, "minutes") * Time.MINUTE;
330                    String message = ParamUtil.getString(actionRequest, "message");
331    
332                    if (minutes <= 0) {
333                            ShutdownUtil.cancel();
334                    }
335                    else {
336                            ShutdownUtil.shutdown(minutes, message);
337                    }
338            }
339    
340            protected void threadDump() throws Exception {
341                    String jvm =
342                            System.getProperty("java.vm.name") + " " +
343                                    System.getProperty("java.vm.version");
344    
345                    StringBundler sb = new StringBundler(
346                            "Full thread dump " + jvm + "\n\n");
347    
348                    Map<Thread, StackTraceElement[]> stackTraces =
349                            Thread.getAllStackTraces();
350    
351                    for (Map.Entry<Thread, StackTraceElement[]> entry :
352                                    stackTraces.entrySet()) {
353    
354                            Thread thread = entry.getKey();
355                            StackTraceElement[] elements = entry.getValue();
356    
357                            sb.append(StringPool.QUOTE);
358                            sb.append(thread.getName());
359                            sb.append(StringPool.QUOTE);
360    
361                            if (thread.getThreadGroup() != null) {
362                                    sb.append(StringPool.SPACE);
363                                    sb.append(StringPool.OPEN_PARENTHESIS);
364                                    sb.append(thread.getThreadGroup().getName());
365                                    sb.append(StringPool.CLOSE_PARENTHESIS);
366                            }
367    
368                            sb.append(", priority=");
369                            sb.append(thread.getPriority());
370                            sb.append(", id=");
371                            sb.append(thread.getId());
372                            sb.append(", state=");
373                            sb.append(thread.getState());
374                            sb.append("\n");
375    
376                            for (int i = 0; i < elements.length; i++) {
377                                    sb.append("\t");
378                                    sb.append(elements[i]);
379                                    sb.append("\n");
380                            }
381    
382                            sb.append("\n");
383                    }
384    
385                    if (_log.isInfoEnabled()) {
386                            _log.info(sb.toString());
387                    }
388                    else {
389                            _log.error(
390                                    "Thread dumps require the log level to be at least INFO for " +
391                                            getClass().getName());
392                    }
393            }
394    
395            protected void updateFileUploads(
396                            ActionRequest actionRequest, PortletPreferences preferences)
397                    throws Exception {
398    
399                    String dlFileExtensions = getFileExtensions(
400                            actionRequest, "dlFileExtensions");
401                    long dlFileMaxSize = ParamUtil.getLong(actionRequest, "dlFileMaxSize");
402                    String igImageExtensions = getFileExtensions(
403                            actionRequest, "igImageExtensions");
404                    long igImageMaxSize = ParamUtil.getLong(
405                            actionRequest, "igImageMaxSize");
406                    long igThumbnailMaxDimension = ParamUtil.getLong(
407                            actionRequest, "igImageThumbnailMaxDimensions");
408                    String journalImageExtensions = getFileExtensions(
409                            actionRequest, "journalImageExtensions");
410                    long journalImageSmallMaxSize = ParamUtil.getLong(
411                            actionRequest, "journalImageSmallMaxSize");
412                    String shoppingImageExtensions = getFileExtensions(
413                            actionRequest, "shoppingImageExtensions");
414                    long scImageMaxSize = ParamUtil.getLong(
415                            actionRequest, "scImageMaxSize");
416                    long scImageThumbnailMaxHeight = ParamUtil.getLong(
417                            actionRequest, "scImageThumbnailMaxHeight");
418                    long scImageThumbnailMaxWidth = ParamUtil.getLong(
419                            actionRequest, "scImageThumbnailMaxWidth");
420                    long shoppingImageLargeMaxSize = ParamUtil.getLong(
421                            actionRequest, "shoppingImageLargeMaxSize");
422                    long shoppingImageMediumMaxSize = ParamUtil.getLong(
423                            actionRequest, "shoppingImageMediumMaxSize");
424                    long shoppingImageSmallMaxSize = ParamUtil.getLong(
425                            actionRequest, "shoppingImageSmallMaxSize");
426                    long uploadServletRequestImplMaxSize = ParamUtil.getLong(
427                            actionRequest, "uploadServletRequestImplMaxSize");
428                    String uploadServletRequestImplTempDir = ParamUtil.getString(
429                            actionRequest, "uploadServletRequestImplTempDir");
430                    long usersImageMaxSize = ParamUtil.getLong(
431                            actionRequest, "usersImageMaxSize");
432    
433                    preferences.setValue(
434                            PropsKeys.DL_FILE_EXTENSIONS, dlFileExtensions);
435                    preferences.setValue(
436                            PropsKeys.DL_FILE_MAX_SIZE, String.valueOf(dlFileMaxSize));
437                    preferences.setValue(
438                            PropsKeys.IG_IMAGE_EXTENSIONS, igImageExtensions);
439                    preferences.setValue(
440                            PropsKeys.IG_IMAGE_MAX_SIZE, String.valueOf(igImageMaxSize));
441                    preferences.setValue(
442                            PropsKeys.IG_IMAGE_THUMBNAIL_MAX_DIMENSION,
443                            String.valueOf(igThumbnailMaxDimension));
444                    preferences.setValue(
445                            PropsKeys.JOURNAL_IMAGE_EXTENSIONS, journalImageExtensions);
446                    preferences.setValue(
447                            PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE,
448                            String.valueOf(journalImageSmallMaxSize));
449                    preferences.setValue(
450                            PropsKeys.SHOPPING_IMAGE_EXTENSIONS, shoppingImageExtensions);
451                    preferences.setValue(
452                            PropsKeys.SHOPPING_IMAGE_LARGE_MAX_SIZE,
453                            String.valueOf(shoppingImageLargeMaxSize));
454                    preferences.setValue(
455                            PropsKeys.SHOPPING_IMAGE_MEDIUM_MAX_SIZE,
456                            String.valueOf(shoppingImageMediumMaxSize));
457                    preferences.setValue(
458                            PropsKeys.SHOPPING_IMAGE_SMALL_MAX_SIZE,
459                            String.valueOf(shoppingImageSmallMaxSize));
460                    preferences.setValue(
461                            PropsKeys.SC_IMAGE_MAX_SIZE, String.valueOf(scImageMaxSize));
462                    preferences.setValue(
463                            PropsKeys.SC_IMAGE_THUMBNAIL_MAX_HEIGHT,
464                            String.valueOf(scImageThumbnailMaxHeight));
465                    preferences.setValue(
466                            PropsKeys.SC_IMAGE_THUMBNAIL_MAX_WIDTH,
467                            String.valueOf(scImageThumbnailMaxWidth));
468                    preferences.setValue(
469                            PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE,
470                            String.valueOf(uploadServletRequestImplMaxSize));
471    
472                    if (Validator.isNotNull(uploadServletRequestImplTempDir)) {
473                            preferences.setValue(
474                                    PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_TEMP_DIR,
475                                    uploadServletRequestImplTempDir);
476                    }
477    
478                    preferences.setValue(
479                            PropsKeys.USERS_IMAGE_MAX_SIZE, String.valueOf(usersImageMaxSize));
480    
481                    preferences.store();
482            }
483    
484            protected void updateLogLevels(ActionRequest actionRequest)
485                    throws Exception {
486    
487                    Enumeration<String> enu = actionRequest.getParameterNames();
488    
489                    while (enu.hasMoreElements()) {
490                            String name = enu.nextElement();
491    
492                            if (name.startsWith("logLevel")) {
493                                    String loggerName = name.substring(8, name.length());
494    
495                                    String priority = ParamUtil.getString(
496                                            actionRequest, name, Level.INFO.toString());
497    
498                                    Log4JUtil.setLevel(loggerName, priority);
499                            }
500                    }
501            }
502    
503            protected void updateMail(
504                            ActionRequest actionRequest, PortletPreferences preferences)
505                    throws Exception {
506    
507                    String advancedProperties = ParamUtil.getString(
508                            actionRequest, "advancedProperties");
509                    String pop3Host = ParamUtil.getString(actionRequest, "pop3Host");
510                    String pop3Password = ParamUtil.getString(
511                            actionRequest, "pop3Password");
512                    int pop3Port = ParamUtil.getInteger(actionRequest, "pop3Port");
513                    boolean pop3Secure = ParamUtil.getBoolean(actionRequest, "pop3Secure");
514                    String pop3User = ParamUtil.getString(actionRequest, "pop3User");
515                    String smtpHost = ParamUtil.getString(actionRequest, "smtpHost");
516                    String smtpPassword = ParamUtil.getString(
517                            actionRequest, "smtpPassword");
518                    int smtpPort = ParamUtil.getInteger(actionRequest, "smtpPort");
519                    boolean smtpSecure = ParamUtil.getBoolean(actionRequest, "smtpSecure");
520                    String smtpUser = ParamUtil.getString(actionRequest, "smtpUser");
521    
522                    String storeProtocol = Account.PROTOCOL_POP;
523    
524                    if (pop3Secure) {
525                            storeProtocol = Account.PROTOCOL_POPS;
526                    }
527    
528                    String transportProtocol = Account.PROTOCOL_SMTP;
529    
530                    if (smtpSecure) {
531                            transportProtocol = Account.PROTOCOL_SMTPS;
532                    }
533    
534                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL, "true");
535                    preferences.setValue(
536                            PropsKeys.MAIL_SESSION_MAIL_ADVANCED_PROPERTIES,
537                            advancedProperties);
538                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_POP3_HOST, pop3Host);
539                    preferences.setValue(
540                            PropsKeys.MAIL_SESSION_MAIL_POP3_PASSWORD, pop3Password);
541                    preferences.setValue(
542                            PropsKeys.MAIL_SESSION_MAIL_POP3_PORT, String.valueOf(pop3Port));
543                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_POP3_USER, pop3User);
544                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_SMTP_HOST, smtpHost);
545                    preferences.setValue(
546                            PropsKeys.MAIL_SESSION_MAIL_SMTP_PASSWORD, smtpPassword);
547                    preferences.setValue(
548                            PropsKeys.MAIL_SESSION_MAIL_SMTP_PORT, String.valueOf(smtpPort));
549                    preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_SMTP_USER, smtpUser);
550                    preferences.setValue(
551                            PropsKeys.MAIL_SESSION_MAIL_STORE_PROTOCOL, storeProtocol);
552                    preferences.setValue(
553                            PropsKeys.MAIL_SESSION_MAIL_TRANSPORT_PROTOCOL, transportProtocol);
554    
555                    preferences.store();
556    
557                    MailServiceUtil.clearSession();
558            }
559    
560            protected void updateOpenOffice(
561                            ActionRequest actionRequest, PortletPreferences preferences)
562                    throws Exception {
563    
564                    boolean enabled = ParamUtil.getBoolean(actionRequest, "enabled");
565                    int port = ParamUtil.getInteger(actionRequest, "port");
566    
567                    preferences.setValue(
568                            PropsKeys.OPENOFFICE_SERVER_ENABLED, String.valueOf(enabled));
569                    preferences.setValue(
570                            PropsKeys.OPENOFFICE_SERVER_PORT, String.valueOf(port));
571    
572                    preferences.store();
573            }
574    
575            protected void verifyPluginTables() throws Exception {
576                    ServiceComponentLocalServiceUtil.verifyDB();
577            }
578    
579            private static Log _log = LogFactoryUtil.getLog(EditServerAction.class);
580    
581    }