1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.admin.action;
16  
17  import com.liferay.mail.service.MailServiceUtil;
18  import com.liferay.portal.convert.ConvertProcess;
19  import com.liferay.portal.kernel.cache.CacheRegistry;
20  import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
21  import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
22  import com.liferay.portal.kernel.log.Log;
23  import com.liferay.portal.kernel.log.LogFactoryUtil;
24  import com.liferay.portal.kernel.mail.Account;
25  import com.liferay.portal.kernel.messaging.DestinationNames;
26  import com.liferay.portal.kernel.messaging.MessageBusUtil;
27  import com.liferay.portal.kernel.scripting.ScriptingException;
28  import com.liferay.portal.kernel.scripting.ScriptingUtil;
29  import com.liferay.portal.kernel.search.Indexer;
30  import com.liferay.portal.kernel.search.SearchEngineUtil;
31  import com.liferay.portal.kernel.servlet.SessionErrors;
32  import com.liferay.portal.kernel.servlet.SessionMessages;
33  import com.liferay.portal.kernel.util.Constants;
34  import com.liferay.portal.kernel.util.InstancePool;
35  import com.liferay.portal.kernel.util.ParamUtil;
36  import com.liferay.portal.kernel.util.PropsKeys;
37  import com.liferay.portal.kernel.util.StringBundler;
38  import com.liferay.portal.kernel.util.StringPool;
39  import com.liferay.portal.kernel.util.StringUtil;
40  import com.liferay.portal.kernel.util.Time;
41  import com.liferay.portal.kernel.util.Validator;
42  import com.liferay.portal.kernel.webcache.WebCachePoolUtil;
43  import com.liferay.portal.model.Portlet;
44  import com.liferay.portal.search.lucene.LuceneIndexer;
45  import com.liferay.portal.security.auth.PrincipalException;
46  import com.liferay.portal.security.permission.PermissionChecker;
47  import com.liferay.portal.service.PortletLocalServiceUtil;
48  import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
49  import com.liferay.portal.struts.PortletAction;
50  import com.liferay.portal.theme.ThemeDisplay;
51  import com.liferay.portal.util.MaintenanceUtil;
52  import com.liferay.portal.util.PortalInstances;
53  import com.liferay.portal.util.PrefsPropsUtil;
54  import com.liferay.portal.util.ShutdownUtil;
55  import com.liferay.portal.util.WebKeys;
56  import com.liferay.portlet.ActionResponseImpl;
57  import com.liferay.util.log4j.Log4JUtil;
58  
59  import java.util.Enumeration;
60  import java.util.Map;
61  
62  import javax.portlet.ActionRequest;
63  import javax.portlet.ActionResponse;
64  import javax.portlet.PortletConfig;
65  import javax.portlet.PortletContext;
66  import javax.portlet.PortletPreferences;
67  import javax.portlet.PortletSession;
68  import javax.portlet.PortletURL;
69  import javax.portlet.WindowState;
70  
71  import org.apache.log4j.Level;
72  import org.apache.log4j.Logger;
73  import org.apache.struts.action.ActionForm;
74  import org.apache.struts.action.ActionMapping;
75  
76  /**
77   * <a href="EditServerAction.java.html"><b><i>View Source</i></b></a>
78   *
79   * @author Brian Wing Shun Chan
80   */
81  public class EditServerAction extends PortletAction {
82  
83      public void processAction(
84              ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
85              ActionRequest actionRequest, ActionResponse actionResponse)
86          throws Exception {
87  
88          ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
89              WebKeys.THEME_DISPLAY);
90  
91          PermissionChecker permissionChecker =
92              themeDisplay.getPermissionChecker();
93  
94          if (!permissionChecker.isOmniadmin()) {
95              SessionErrors.add(
96                  actionRequest, PrincipalException.class.getName());
97  
98              setForward(actionRequest, "portlet.admin.error");
99  
100             return;
101         }
102 
103         PortletPreferences preferences = PrefsPropsUtil.getPreferences();
104 
105         String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
106 
107         String redirect = null;
108 
109         if (cmd.equals("addLogLevel")) {
110             addLogLevel(actionRequest);
111         }
112         else if (cmd.equals("cacheDb")) {
113             cacheDb();
114         }
115         else if (cmd.equals("cacheMulti")) {
116             cacheMulti();
117         }
118         else if (cmd.equals("cacheSingle")) {
119             cacheSingle();
120         }
121         else if (cmd.startsWith("convertProcess.")) {
122             redirect = convertProcess(actionRequest, actionResponse, cmd);
123         }
124         else if (cmd.equals("gc")) {
125             gc();
126         }
127         else if (cmd.equals("reindex")) {
128             reindex(actionRequest);
129         }
130         else if (cmd.equals("runScript")) {
131             runScript(portletConfig, actionRequest, actionResponse);
132         }
133         else if (cmd.equals("shutdown")) {
134             shutdown(actionRequest);
135         }
136         else if (cmd.equals("threadDump")) {
137             threadDump();
138         }
139         else if (cmd.equals("updateFileUploads")) {
140             updateFileUploads(actionRequest, preferences);
141         }
142         else if (cmd.equals("updateLogLevels")) {
143             updateLogLevels(actionRequest);
144         }
145         else if (cmd.equals("updateMail")) {
146             updateMail(actionRequest, preferences);
147         }
148         else if (cmd.equals("updateOpenOffice")) {
149             updateOpenOffice(actionRequest, preferences);
150         }
151         else if (cmd.equals("verifyPluginTables")) {
152             verifyPluginTables();
153         }
154 
155         sendRedirect(actionRequest, actionResponse, redirect);
156     }
157 
158     protected void addLogLevel(ActionRequest actionRequest) throws Exception {
159         String loggerName = ParamUtil.getString(actionRequest, "loggerName");
160         String priority = ParamUtil.getString(actionRequest, "priority");
161 
162         Logger logger = Logger.getLogger(loggerName);
163 
164         logger.setLevel(Level.toLevel(priority));
165     }
166 
167     protected void cacheDb() throws Exception {
168         CacheRegistry.clear();
169     }
170 
171     protected void cacheMulti() throws Exception {
172         MultiVMPoolUtil.clear();
173     }
174 
175     protected void cacheSingle() throws Exception {
176         WebCachePoolUtil.clear();
177     }
178 
179     protected String convertProcess(
180             ActionRequest actionRequest, ActionResponse actionResponse,
181             String cmd)
182         throws Exception {
183 
184         ActionResponseImpl actionResponseImpl =
185             (ActionResponseImpl)actionResponse;
186 
187         PortletSession portletSession = actionRequest.getPortletSession();
188 
189         String className = StringUtil.replaceFirst(
190             cmd, "convertProcess.", StringPool.BLANK);
191 
192         ConvertProcess convertProcess = (ConvertProcess)InstancePool.get(
193             className);
194 
195         String[] parameters = convertProcess.getParameterNames();
196 
197         if (parameters != null) {
198             String[] values = new String[parameters.length];
199 
200             for (int i = 0; i < parameters.length; i++) {
201                 String parameter =
202                     className + StringPool.PERIOD + parameters[i];
203 
204                 if (parameters[i].contains(StringPool.EQUAL)) {
205                     String[] parameterPair = StringUtil.split(
206                         parameters[i], StringPool.EQUAL);
207 
208                     parameter =
209                         className + StringPool.PERIOD + parameterPair[0];
210                 }
211 
212                 values[i] = ParamUtil.getString(actionRequest, parameter);
213             }
214 
215             convertProcess.setParameterValues(values);
216         }
217 
218         String path = convertProcess.getPath();
219 
220         if (path != null) {
221             PortletURL portletURL = actionResponseImpl.createRenderURL();
222 
223             portletURL.setWindowState(WindowState.MAXIMIZED);
224 
225             portletURL.setParameter("struts_action", path);
226 
227             return portletURL.toString();
228         }
229         else {
230             MaintenanceUtil.maintain(portletSession.getId(), className);
231 
232             MessageBusUtil.sendMessage(
233                 DestinationNames.CONVERT_PROCESS, className);
234 
235             return null;
236         }
237     }
238 
239     protected void gc() throws Exception {
240         Runtime.getRuntime().gc();
241     }
242 
243     protected String getFileExtensions(
244         ActionRequest actionRequest, String name) {
245 
246         String value = ParamUtil.getString(actionRequest, name);
247 
248         return value.replace(", .", ",.");
249     }
250 
251     protected void reindex(ActionRequest actionRequest) throws Exception {
252         String portletId = ParamUtil.getString(actionRequest, "portletId");
253 
254         long[] companyIds = PortalInstances.getCompanyIds();
255 
256         if (Validator.isNull(portletId)) {
257             for (long companyId : companyIds) {
258                 try {
259                     LuceneIndexer indexer = new LuceneIndexer(companyId);
260 
261                     indexer.reindex();
262                 }
263                 catch (Exception e) {
264                     _log.error(e, e);
265                 }
266             }
267         }
268         else {
269             Portlet portlet = PortletLocalServiceUtil.getPortletById(
270                 companyIds[0], portletId);
271 
272             if (portlet == null) {
273                 return;
274             }
275 
276             Indexer indexer = portlet.getIndexerInstance();
277 
278             if (indexer == null) {
279                 return;
280             }
281 
282             for (long companyId : companyIds) {
283                 try {
284                     SearchEngineUtil.deletePortletDocuments(
285                         companyId, portletId);
286 
287                     indexer.reindex(new String[] {String.valueOf(companyId)});
288                 }
289                 catch (Exception e) {
290                     _log.error(e, e);
291                 }
292             }
293         }
294     }
295 
296     protected void runScript(
297             PortletConfig portletConfig, ActionRequest actionRequest,
298             ActionResponse actionResponse)
299         throws Exception {
300 
301         String language = ParamUtil.getString(actionRequest, "language");
302         String script = ParamUtil.getString(actionRequest, "script");
303 
304         PortletContext portletContext = portletConfig.getPortletContext();
305 
306         Map<String, Object> portletObjects = ScriptingUtil.getPortletObjects(
307             portletConfig, portletContext, actionRequest, actionResponse);
308 
309         UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
310             new UnsyncByteArrayOutputStream();
311 
312         portletObjects.put("out", unsyncByteArrayOutputStream);
313 
314         try {
315             ScriptingUtil.exec(null, portletObjects, language, script);
316 
317             SessionMessages.add(
318                 actionRequest, "script_output",
319                 unsyncByteArrayOutputStream.toString());
320         }
321         catch (ScriptingException se) {
322             SessionErrors.add(
323                 actionRequest, ScriptingException.class.getName(), se);
324 
325             _log.error(se.getMessage());
326         }
327     }
328 
329     protected void shutdown(ActionRequest actionRequest) throws Exception {
330         long minutes =
331             ParamUtil.getInteger(actionRequest, "minutes") * Time.MINUTE;
332         String message = ParamUtil.getString(actionRequest, "message");
333 
334         if (minutes <= 0) {
335             ShutdownUtil.cancel();
336         }
337         else {
338             ShutdownUtil.shutdown(minutes, message);
339         }
340     }
341 
342     protected void threadDump() throws Exception {
343         String jvm =
344             System.getProperty("java.vm.name") + " " +
345                 System.getProperty("java.vm.version");
346 
347         StringBundler sb = new StringBundler(
348             "Full thread dump " + jvm + "\n\n");
349 
350         Map<Thread, StackTraceElement[]> stackTraces =
351             Thread.getAllStackTraces();
352 
353         for (Thread thread : stackTraces.keySet()) {
354             StackTraceElement[] elements = stackTraces.get(thread);
355 
356             sb.append(StringPool.QUOTE);
357             sb.append(thread.getName());
358             sb.append(StringPool.QUOTE);
359 
360             if (thread.getThreadGroup() != null) {
361                 sb.append(StringPool.SPACE);
362                 sb.append(StringPool.OPEN_PARENTHESIS);
363                 sb.append(thread.getThreadGroup().getName());
364                 sb.append(StringPool.CLOSE_PARENTHESIS);
365             }
366 
367             sb.append(", priority=");
368             sb.append(thread.getPriority());
369             sb.append(", id=");
370             sb.append(thread.getId());
371             sb.append(", state=");
372             sb.append(thread.getState());
373             sb.append("\n");
374 
375             for (int i = 0; i < elements.length; i++) {
376                 sb.append("\t");
377                 sb.append(elements[i]);
378                 sb.append("\n");
379             }
380 
381             sb.append("\n");
382         }
383 
384         if (_log.isInfoEnabled()) {
385             _log.info(sb.toString());
386         }
387         else {
388             _log.error(
389                 "Thread dumps require the log level to be at least INFO for " +
390                     getClass().getName());
391         }
392     }
393 
394     protected void updateFileUploads(
395             ActionRequest actionRequest, PortletPreferences preferences)
396         throws Exception {
397 
398         String dlFileExtensions = getFileExtensions(
399             actionRequest, "dlFileExtensions");
400         long dlFileMaxSize = ParamUtil.getLong(actionRequest, "dlFileMaxSize");
401         String igImageExtensions = getFileExtensions(
402             actionRequest, "igImageExtensions");
403         long igImageMaxSize = ParamUtil.getLong(
404             actionRequest, "igImageMaxSize");
405         long igThumbnailMaxDimension = ParamUtil.getLong(
406             actionRequest, "igImageThumbnailMaxDimensions");
407         String journalImageExtensions = getFileExtensions(
408             actionRequest, "journalImageExtensions");
409         long journalImageSmallMaxSize = ParamUtil.getLong(
410             actionRequest, "journalImageSmallMaxSize");
411         String shoppingImageExtensions = getFileExtensions(
412             actionRequest, "shoppingImageExtensions");
413         long scImageMaxSize = ParamUtil.getLong(
414             actionRequest, "scImageMaxSize");
415         long scImageThumbnailMaxHeight = ParamUtil.getLong(
416             actionRequest, "scImageThumbnailMaxHeight");
417         long scImageThumbnailMaxWidth = ParamUtil.getLong(
418             actionRequest, "scImageThumbnailMaxWidth");
419         long shoppingImageLargeMaxSize = ParamUtil.getLong(
420             actionRequest, "shoppingImageLargeMaxSize");
421         long shoppingImageMediumMaxSize = ParamUtil.getLong(
422             actionRequest, "shoppingImageMediumMaxSize");
423         long shoppingImageSmallMaxSize = ParamUtil.getLong(
424             actionRequest, "shoppingImageSmallMaxSize");
425         long uploadServletRequestImplMaxSize = ParamUtil.getLong(
426             actionRequest, "uploadServletRequestImplMaxSize");
427         String uploadServletRequestImplTempDir = ParamUtil.getString(
428             actionRequest, "uploadServletRequestImplTempDir");
429         long usersImageMaxSize = ParamUtil.getLong(
430             actionRequest, "usersImageMaxSize");
431 
432         preferences.setValue(
433             PropsKeys.DL_FILE_EXTENSIONS, dlFileExtensions);
434         preferences.setValue(
435             PropsKeys.DL_FILE_MAX_SIZE, String.valueOf(dlFileMaxSize));
436         preferences.setValue(
437             PropsKeys.IG_IMAGE_EXTENSIONS, igImageExtensions);
438         preferences.setValue(
439             PropsKeys.IG_IMAGE_MAX_SIZE, String.valueOf(igImageMaxSize));
440         preferences.setValue(
441             PropsKeys.IG_IMAGE_THUMBNAIL_MAX_DIMENSION,
442             String.valueOf(igThumbnailMaxDimension));
443         preferences.setValue(
444             PropsKeys.JOURNAL_IMAGE_EXTENSIONS, journalImageExtensions);
445         preferences.setValue(
446             PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE,
447             String.valueOf(journalImageSmallMaxSize));
448         preferences.setValue(
449             PropsKeys.SHOPPING_IMAGE_EXTENSIONS, shoppingImageExtensions);
450         preferences.setValue(
451             PropsKeys.SHOPPING_IMAGE_LARGE_MAX_SIZE,
452             String.valueOf(shoppingImageLargeMaxSize));
453         preferences.setValue(
454             PropsKeys.SHOPPING_IMAGE_MEDIUM_MAX_SIZE,
455             String.valueOf(shoppingImageMediumMaxSize));
456         preferences.setValue(
457             PropsKeys.SHOPPING_IMAGE_SMALL_MAX_SIZE,
458             String.valueOf(shoppingImageSmallMaxSize));
459         preferences.setValue(
460             PropsKeys.SC_IMAGE_MAX_SIZE, String.valueOf(scImageMaxSize));
461         preferences.setValue(
462             PropsKeys.SC_IMAGE_THUMBNAIL_MAX_HEIGHT,
463             String.valueOf(scImageThumbnailMaxHeight));
464         preferences.setValue(
465             PropsKeys.SC_IMAGE_THUMBNAIL_MAX_WIDTH,
466             String.valueOf(scImageThumbnailMaxWidth));
467         preferences.setValue(
468             PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE,
469             String.valueOf(uploadServletRequestImplMaxSize));
470 
471         if (Validator.isNotNull(uploadServletRequestImplTempDir)) {
472             preferences.setValue(
473                 PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_TEMP_DIR,
474                 uploadServletRequestImplTempDir);
475         }
476 
477         preferences.setValue(
478             PropsKeys.USERS_IMAGE_MAX_SIZE, String.valueOf(usersImageMaxSize));
479 
480         preferences.store();
481     }
482 
483     protected void updateLogLevels(ActionRequest actionRequest)
484         throws Exception {
485 
486         Enumeration<String> enu = actionRequest.getParameterNames();
487 
488         while (enu.hasMoreElements()) {
489             String name = enu.nextElement();
490 
491             if (name.startsWith("logLevel")) {
492                 String loggerName = name.substring(8, name.length());
493 
494                 String priority = ParamUtil.getString(
495                     actionRequest, name, Level.INFO.toString());
496 
497                 Log4JUtil.setLevel(loggerName, priority);
498             }
499         }
500     }
501 
502     protected void updateMail(
503             ActionRequest actionRequest, PortletPreferences preferences)
504         throws Exception {
505 
506         String advancedProperties = ParamUtil.getString(
507             actionRequest, "advancedProperties");
508         String pop3Host = ParamUtil.getString(actionRequest, "pop3Host");
509         String pop3Password = ParamUtil.getString(
510             actionRequest, "pop3Password");
511         int pop3Port = ParamUtil.getInteger(actionRequest, "pop3Port");
512         boolean pop3Secure = ParamUtil.getBoolean(actionRequest, "pop3Secure");
513         String pop3User = ParamUtil.getString(actionRequest, "pop3User");
514         String smtpHost = ParamUtil.getString(actionRequest, "smtpHost");
515         String smtpPassword = ParamUtil.getString(
516             actionRequest, "smtpPassword");
517         int smtpPort = ParamUtil.getInteger(actionRequest, "smtpPort");
518         boolean smtpSecure = ParamUtil.getBoolean(actionRequest, "smtpSecure");
519         String smtpUser = ParamUtil.getString(actionRequest, "smtpUser");
520 
521         String storeProtocol = Account.PROTOCOL_POP;
522 
523         if (pop3Secure) {
524             storeProtocol = Account.PROTOCOL_POPS;
525         }
526 
527         String transportProtocol = Account.PROTOCOL_SMTP;
528 
529         if (smtpSecure) {
530             transportProtocol = Account.PROTOCOL_SMTPS;
531         }
532 
533         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL, "true");
534         preferences.setValue(
535             PropsKeys.MAIL_SESSION_MAIL_ADVANCED_PROPERTIES,
536             advancedProperties);
537         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_POP3_HOST, pop3Host);
538         preferences.setValue(
539             PropsKeys.MAIL_SESSION_MAIL_POP3_PASSWORD, pop3Password);
540         preferences.setValue(
541             PropsKeys.MAIL_SESSION_MAIL_POP3_PORT, String.valueOf(pop3Port));
542         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_POP3_USER, pop3User);
543         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_SMTP_HOST, smtpHost);
544         preferences.setValue(
545             PropsKeys.MAIL_SESSION_MAIL_SMTP_PASSWORD, smtpPassword);
546         preferences.setValue(
547             PropsKeys.MAIL_SESSION_MAIL_SMTP_PORT, String.valueOf(smtpPort));
548         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_SMTP_USER, smtpUser);
549         preferences.setValue(
550             PropsKeys.MAIL_SESSION_MAIL_STORE_PROTOCOL, storeProtocol);
551         preferences.setValue(
552             PropsKeys.MAIL_SESSION_MAIL_TRANSPORT_PROTOCOL, transportProtocol);
553 
554         preferences.store();
555 
556         MailServiceUtil.clearSession();
557     }
558 
559     protected void updateOpenOffice(
560             ActionRequest actionRequest, PortletPreferences preferences)
561         throws Exception {
562 
563         boolean enabled = ParamUtil.getBoolean(actionRequest, "enabled");
564         int port = ParamUtil.getInteger(actionRequest, "port");
565 
566         preferences.setValue(
567             PropsKeys.OPENOFFICE_SERVER_ENABLED, String.valueOf(enabled));
568         preferences.setValue(
569             PropsKeys.OPENOFFICE_SERVER_PORT, String.valueOf(port));
570 
571         preferences.store();
572     }
573 
574     protected void verifyPluginTables() throws Exception {
575         ServiceComponentLocalServiceUtil.verifyDB();
576     }
577 
578     private static Log _log = LogFactoryUtil.getLog(EditServerAction.class);
579 
580 }