1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.admin.action;
24  
25  import com.liferay.mail.service.MailServiceUtil;
26  import com.liferay.portal.kernel.cache.CacheRegistry;
27  import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
28  import com.liferay.portal.kernel.log.Log;
29  import com.liferay.portal.kernel.log.LogFactoryUtil;
30  import com.liferay.portal.kernel.mail.Account;
31  import com.liferay.portal.kernel.messaging.DestinationNames;
32  import com.liferay.portal.kernel.messaging.MessageBusUtil;
33  import com.liferay.portal.kernel.search.Indexer;
34  import com.liferay.portal.kernel.search.SearchEngineUtil;
35  import com.liferay.portal.kernel.servlet.SessionErrors;
36  import com.liferay.portal.kernel.util.Constants;
37  import com.liferay.portal.kernel.util.ParamUtil;
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.struts.PortletAction;
49  import com.liferay.portal.theme.ThemeDisplay;
50  import com.liferay.portal.util.MaintenanceUtil;
51  import com.liferay.portal.util.PortalInstances;
52  import com.liferay.portal.util.PrefsPropsUtil;
53  import com.liferay.portal.util.PropsKeys;
54  import com.liferay.portal.util.ShutdownUtil;
55  import com.liferay.portal.util.WebKeys;
56  import com.liferay.util.log4j.Log4JUtil;
57  
58  import java.util.Enumeration;
59  import java.util.Map;
60  
61  import javax.portlet.ActionRequest;
62  import javax.portlet.ActionResponse;
63  import javax.portlet.PortletConfig;
64  import javax.portlet.PortletPreferences;
65  import javax.portlet.PortletSession;
66  
67  import org.apache.log4j.Level;
68  import org.apache.log4j.Logger;
69  import org.apache.struts.action.ActionForm;
70  import org.apache.struts.action.ActionMapping;
71  
72  /**
73   * <a href="EditServerAction.java.html"><b><i>View Source</i></b></a>
74   *
75   * @author Brian Wing Shun Chan
76   *
77   */
78  public class EditServerAction extends PortletAction {
79  
80      public void processAction(
81              ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
82              ActionRequest actionRequest, ActionResponse actionResponse)
83          throws Exception {
84  
85          ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
86              WebKeys.THEME_DISPLAY);
87  
88          PermissionChecker permissionChecker =
89              themeDisplay.getPermissionChecker();
90  
91          if (!permissionChecker.isOmniadmin()) {
92              SessionErrors.add(
93                  actionRequest, PrincipalException.class.getName());
94  
95              setForward(actionRequest, "portlet.admin.error");
96  
97              return;
98          }
99  
100         PortletPreferences preferences = PrefsPropsUtil.getPreferences();
101 
102         String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
103 
104         if (cmd.equals("addLogLevel")) {
105             addLogLevel(actionRequest);
106         }
107         else if (cmd.equals("cacheDb")) {
108             cacheDb();
109         }
110         else if (cmd.equals("cacheMulti")) {
111             cacheMulti();
112         }
113         else if (cmd.equals("cacheSingle")) {
114             cacheSingle();
115         }
116         else if (cmd.startsWith("convertProcess.")) {
117             convertProcess(actionRequest, cmd);
118         }
119         else if (cmd.equals("gc")) {
120             gc();
121         }
122         else if (cmd.equals("reIndex")) {
123             reIndex(actionRequest);
124         }
125         else if (cmd.equals("shutdown")) {
126             shutdown(actionRequest);
127         }
128         else if (cmd.equals("threadDump")) {
129             threadDump();
130         }
131         else if (cmd.equals("updateFileUploads")) {
132             updateFileUploads(actionRequest, preferences);
133         }
134         else if (cmd.equals("updateLogLevels")) {
135             updateLogLevels(actionRequest);
136         }
137         else if (cmd.equals("updateMail")) {
138             updateMail(actionRequest, preferences);
139         }
140         else if (cmd.equals("updateOpenOffice")) {
141             updateOpenOffice(actionRequest, preferences);
142         }
143 
144         sendRedirect(actionRequest, actionResponse);
145     }
146 
147     protected void addLogLevel(ActionRequest actionRequest) throws Exception {
148         String loggerName = ParamUtil.getString(actionRequest, "loggerName");
149         String priority = ParamUtil.getString(actionRequest, "priority");
150 
151         Logger logger = Logger.getLogger(loggerName);
152 
153         logger.setLevel(Level.toLevel(priority));
154     }
155 
156     protected void cacheDb() throws Exception {
157         CacheRegistry.clear();
158     }
159 
160     protected void cacheMulti() throws Exception {
161         MultiVMPoolUtil.clear();
162     }
163 
164     protected void cacheSingle() throws Exception {
165         WebCachePoolUtil.clear();
166     }
167 
168     protected void convertProcess(ActionRequest actionRequest, String cmd)
169         throws Exception {
170 
171         PortletSession portletSession = actionRequest.getPortletSession();
172 
173         String className = StringUtil.replaceFirst(
174             cmd, "convertProcess.", StringPool.BLANK);
175 
176         MaintenanceUtil.maintain(portletSession.getId(), className);
177 
178         MessageBusUtil.sendMessage(DestinationNames.CONVERT_PROCESS, className);
179     }
180 
181     protected void gc() throws Exception {
182         Runtime.getRuntime().gc();
183     }
184 
185     protected String getFileExtensions(
186         ActionRequest actionRequest, String name) {
187 
188         String value = ParamUtil.getString(actionRequest, name);
189 
190         return value.replace(", .", ",.");
191     }
192 
193     protected void reIndex(ActionRequest actionRequest) throws Exception {
194         String portletId = ParamUtil.getString(actionRequest, "portletId");
195 
196         long[] companyIds = PortalInstances.getCompanyIds();
197 
198         if (Validator.isNull(portletId)) {
199             for (long companyId : companyIds) {
200                 try {
201                     LuceneIndexer indexer = new LuceneIndexer(companyId);
202 
203                     indexer.reIndex();
204                 }
205                 catch (Exception e) {
206                     _log.error(e, e);
207                 }
208             }
209         }
210         else {
211             Portlet portlet = PortletLocalServiceUtil.getPortletById(
212                 companyIds[0], portletId);
213 
214             if (portlet == null) {
215                 return;
216             }
217 
218             Indexer indexer = portlet.getIndexerInstance();
219 
220             if (indexer == null) {
221                 return;
222             }
223 
224             for (long companyId : companyIds) {
225                 try {
226                     SearchEngineUtil.deletePortletDocuments(
227                         companyId, portletId);
228 
229                     indexer.reIndex(new String[] {String.valueOf(companyId)});
230                 }
231                 catch (Exception e) {
232                     _log.error(e, e);
233                 }
234             }
235         }
236     }
237 
238     protected void shutdown(ActionRequest actionRequest) throws Exception {
239         long minutes =
240             ParamUtil.getInteger(actionRequest, "minutes") * Time.MINUTE;
241         String message = ParamUtil.getString(actionRequest, "message");
242 
243         if (minutes <= 0) {
244             ShutdownUtil.cancel();
245         }
246         else {
247             ShutdownUtil.shutdown(minutes, message);
248         }
249     }
250 
251     protected void threadDump() throws Exception {
252         String jvm =
253             System.getProperty("java.vm.name") + " " +
254                 System.getProperty("java.vm.version");
255 
256         StringBuilder sb = new StringBuilder(
257             "Full thread dump " + jvm + "\n\n");
258 
259         Map<Thread, StackTraceElement[]> stackTraces =
260             Thread.getAllStackTraces();
261 
262         for (Thread thread : stackTraces.keySet()) {
263             StackTraceElement[] elements = stackTraces.get(thread);
264 
265             sb.append(StringPool.QUOTE);
266             sb.append(thread.getName());
267             sb.append(StringPool.QUOTE);
268 
269             if (thread.getThreadGroup() != null) {
270                 sb.append(StringPool.SPACE);
271                 sb.append(StringPool.OPEN_PARENTHESIS);
272                 sb.append(thread.getThreadGroup().getName());
273                 sb.append(StringPool.CLOSE_PARENTHESIS);
274             }
275 
276             sb.append(", priority=" + thread.getPriority());
277             sb.append(", id=" + thread.getId());
278             sb.append(", state=" + thread.getState());
279             sb.append("\n");
280 
281             for (int i = 0; i < elements.length; i++) {
282                 sb.append("\t" + elements[i] + "\n");
283             }
284 
285             sb.append("\n");
286         }
287 
288         if (_log.isInfoEnabled()) {
289             _log.info(sb.toString());
290         }
291         else {
292             _log.error(
293                 "Thread dumps require the log level to be at least INFO for " +
294                     getClass().getName());
295         }
296     }
297 
298     protected void updateFileUploads(
299             ActionRequest actionRequest, PortletPreferences preferences)
300         throws Exception {
301 
302         String dlFileExtensions = getFileExtensions(
303             actionRequest, "dlFileExtensions");
304         long dlFileMaxSize = ParamUtil.getLong(actionRequest, "dlFileMaxSize");
305         String igImageExtensions = getFileExtensions(
306             actionRequest, "igImageExtensions");
307         long igImageMaxSize = ParamUtil.getLong(
308             actionRequest, "igImageMaxSize");
309         String igThumbnailMaxDimension = getFileExtensions(
310             actionRequest, "igThumbnailMaxDimension");
311         String journalImageExtensions = getFileExtensions(
312             actionRequest, "journalImageExtensions");
313         long journalImageSmallMaxSize = ParamUtil.getLong(
314             actionRequest, "journalImageSmallMaxSize");
315         String shoppingImageExtensions = getFileExtensions(
316             actionRequest, "shoppingImageExtensions");
317         long scImageMaxSize = ParamUtil.getLong(
318             actionRequest, "scImageMaxSize");
319         long scImageThumbnailMaxHeight = ParamUtil.getLong(
320             actionRequest, "scImageThumbnailMaxHeight");
321         long scImageThumbnailMaxWidth = ParamUtil.getLong(
322             actionRequest, "scImageThumbnailMaxWidth");
323         long shoppingImageLargeMaxSize = ParamUtil.getLong(
324             actionRequest, "shoppingImageLargeMaxSize");
325         long shoppingImageMediumMaxSize = ParamUtil.getLong(
326             actionRequest, "shoppingImageMediumMaxSize");
327         long shoppingImageSmallMaxSize = ParamUtil.getLong(
328             actionRequest, "shoppingImageSmallMaxSize");
329         long uploadServletRequestImplMaxSize = ParamUtil.getLong(
330             actionRequest, "uploadServletRequestImplMaxSize");
331         String uploadServletRequestImplTempDir = ParamUtil.getString(
332             actionRequest, "uploadServletRequestImplTempDir");
333         long usersImageMaxSize = ParamUtil.getLong(
334             actionRequest, "usersImageMaxSize");
335 
336         preferences.setValue(
337             PropsKeys.DL_FILE_EXTENSIONS, dlFileExtensions);
338         preferences.setValue(
339             PropsKeys.DL_FILE_MAX_SIZE, String.valueOf(dlFileMaxSize));
340         preferences.setValue(
341             PropsKeys.IG_IMAGE_EXTENSIONS, igImageExtensions);
342         preferences.setValue(
343             PropsKeys.IG_IMAGE_MAX_SIZE, String.valueOf(igImageMaxSize));
344         preferences.setValue(
345             PropsKeys.IG_IMAGE_THUMBNAIL_MAX_DIMENSION,
346             igThumbnailMaxDimension);
347         preferences.setValue(
348             PropsKeys.JOURNAL_IMAGE_EXTENSIONS, journalImageExtensions);
349         preferences.setValue(
350             PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE,
351             String.valueOf(journalImageSmallMaxSize));
352         preferences.setValue(
353             PropsKeys.SHOPPING_IMAGE_EXTENSIONS, shoppingImageExtensions);
354         preferences.setValue(
355             PropsKeys.SHOPPING_IMAGE_LARGE_MAX_SIZE,
356             String.valueOf(shoppingImageLargeMaxSize));
357         preferences.setValue(
358             PropsKeys.SHOPPING_IMAGE_MEDIUM_MAX_SIZE,
359             String.valueOf(shoppingImageMediumMaxSize));
360         preferences.setValue(
361             PropsKeys.SHOPPING_IMAGE_SMALL_MAX_SIZE,
362             String.valueOf(shoppingImageSmallMaxSize));
363         preferences.setValue(
364             PropsKeys.SC_IMAGE_MAX_SIZE, String.valueOf(scImageMaxSize));
365         preferences.setValue(
366             PropsKeys.SC_IMAGE_THUMBNAIL_MAX_HEIGHT,
367             String.valueOf(scImageThumbnailMaxHeight));
368         preferences.setValue(
369             PropsKeys.SC_IMAGE_THUMBNAIL_MAX_WIDTH,
370             String.valueOf(scImageThumbnailMaxWidth));
371         preferences.setValue(
372             PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE,
373             String.valueOf(uploadServletRequestImplMaxSize));
374 
375         if (Validator.isNotNull(uploadServletRequestImplTempDir)) {
376             preferences.setValue(
377                 PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_TEMP_DIR,
378                 uploadServletRequestImplTempDir);
379         }
380 
381         preferences.setValue(
382             PropsKeys.USERS_IMAGE_MAX_SIZE, String.valueOf(usersImageMaxSize));
383 
384         preferences.store();
385     }
386 
387     protected void updateLogLevels(ActionRequest actionRequest)
388         throws Exception {
389 
390         Enumeration<String> enu = actionRequest.getParameterNames();
391 
392         while (enu.hasMoreElements()) {
393             String name = enu.nextElement();
394 
395             if (name.startsWith("logLevel")) {
396                 String loggerName = name.substring(8, name.length());
397 
398                 String priority = ParamUtil.getString(
399                     actionRequest, name, Level.INFO.toString());
400 
401                 Log4JUtil.setLevel(loggerName, priority);
402             }
403         }
404     }
405 
406     protected void updateMail(
407             ActionRequest actionRequest, PortletPreferences preferences)
408         throws Exception {
409 
410         String advancedProperties = ParamUtil.getString(
411             actionRequest, "advancedProperties");
412         String pop3Host = ParamUtil.getString(actionRequest, "pop3Host");
413         String pop3Password = ParamUtil.getString(
414             actionRequest, "pop3Password");
415         int pop3Port = ParamUtil.getInteger(actionRequest, "pop3Port");
416         boolean pop3Secure = ParamUtil.getBoolean(actionRequest, "pop3Secure");
417         String pop3User = ParamUtil.getString(actionRequest, "pop3User");
418         String smtpHost = ParamUtil.getString(actionRequest, "smtpHost");
419         String smtpPassword = ParamUtil.getString(
420             actionRequest, "smtpPassword");
421         int smtpPort = ParamUtil.getInteger(actionRequest, "smtpPort");
422         boolean smtpSecure = ParamUtil.getBoolean(actionRequest, "smtpSecure");
423         String smtpUser = ParamUtil.getString(actionRequest, "smtpUser");
424 
425         String storeProtocol = Account.PROTOCOL_POP;
426 
427         if (pop3Secure) {
428             storeProtocol = Account.PROTOCOL_POPS;
429         }
430 
431         String transportProtocol = Account.PROTOCOL_SMTP;
432 
433         if (smtpSecure) {
434             transportProtocol = Account.PROTOCOL_SMTPS;
435         }
436 
437         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL, "true");
438         preferences.setValue(
439             PropsKeys.MAIL_SESSION_MAIL_ADVANCED_PROPERTIES,
440             advancedProperties);
441         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_POP3_HOST, pop3Host);
442         preferences.setValue(
443             PropsKeys.MAIL_SESSION_MAIL_POP3_PASSWORD, pop3Password);
444         preferences.setValue(
445             PropsKeys.MAIL_SESSION_MAIL_POP3_PORT, String.valueOf(pop3Port));
446         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_POP3_USER, pop3User);
447         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_SMTP_HOST, smtpHost);
448         preferences.setValue(
449             PropsKeys.MAIL_SESSION_MAIL_SMTP_PASSWORD, smtpPassword);
450         preferences.setValue(
451             PropsKeys.MAIL_SESSION_MAIL_SMTP_PORT, String.valueOf(smtpPort));
452         preferences.setValue(PropsKeys.MAIL_SESSION_MAIL_SMTP_USER, smtpUser);
453         preferences.setValue(
454             PropsKeys.MAIL_SESSION_MAIL_STORE_PROTOCOL, storeProtocol);
455         preferences.setValue(
456             PropsKeys.MAIL_SESSION_MAIL_TRANSPORT_PROTOCOL, transportProtocol);
457 
458         preferences.store();
459 
460         MailServiceUtil.clearSession();
461     }
462 
463     protected void updateOpenOffice(
464             ActionRequest actionRequest, PortletPreferences preferences)
465         throws Exception {
466 
467         boolean enabled = ParamUtil.getBoolean(actionRequest, "enabled");
468         int port = ParamUtil.getInteger(actionRequest, "port");
469 
470         preferences.setValue(
471             PropsKeys.OPENOFFICE_SERVER_ENABLED, String.valueOf(enabled));
472         preferences.setValue(
473             PropsKeys.OPENOFFICE_SERVER_PORT, String.valueOf(port));
474 
475         preferences.store();
476     }
477 
478     private static Log _log = LogFactoryUtil.getLog(EditServerAction.class);
479 
480 }