001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portlet.admin.action;
022:
023: import com.liferay.portal.kernel.cache.CacheRegistry;
024: import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
025: import com.liferay.portal.kernel.security.permission.PermissionChecker;
026: import com.liferay.portal.kernel.util.Constants;
027: import com.liferay.portal.kernel.util.ParamUtil;
028: import com.liferay.portal.kernel.util.PortalClassInvoker;
029: import com.liferay.portal.kernel.util.StringPool;
030: import com.liferay.portal.kernel.util.Validator;
031: import com.liferay.portal.kernel.webcache.WebCachePoolUtil;
032: import com.liferay.portal.lastmodified.LastModifiedCSS;
033: import com.liferay.portal.lastmodified.LastModifiedJavaScript;
034: import com.liferay.portal.lucene.LuceneIndexer;
035: import com.liferay.portal.security.auth.PrincipalException;
036: import com.liferay.portal.struts.PortletAction;
037: import com.liferay.portal.struts.StrutsUtil;
038: import com.liferay.portal.theme.ThemeDisplay;
039: import com.liferay.portal.util.PortalInstances;
040: import com.liferay.portal.util.PortalUtil;
041: import com.liferay.portal.util.PrefsPropsUtil;
042: import com.liferay.portal.util.PropsUtil;
043: import com.liferay.portal.util.ShutdownUtil;
044: import com.liferay.portal.util.WebKeys;
045: import com.liferay.util.Time;
046: import com.liferay.util.servlet.NullServletResponse;
047: import com.liferay.util.servlet.SessionErrors;
048:
049: import java.lang.reflect.Method;
050:
051: import java.util.Enumeration;
052: import java.util.Iterator;
053: import java.util.Map;
054: import java.util.Set;
055: import java.util.TreeSet;
056:
057: import javax.portlet.ActionRequest;
058: import javax.portlet.ActionResponse;
059: import javax.portlet.PortletConfig;
060: import javax.portlet.PortletPreferences;
061:
062: import javax.servlet.RequestDispatcher;
063: import javax.servlet.ServletContext;
064: import javax.servlet.http.HttpServletRequest;
065: import javax.servlet.http.HttpServletResponse;
066:
067: import org.apache.commons.logging.Log;
068: import org.apache.commons.logging.LogFactory;
069: import org.apache.log4j.Level;
070: import org.apache.log4j.Logger;
071: import org.apache.struts.action.ActionForm;
072: import org.apache.struts.action.ActionMapping;
073:
074: import org.dom4j.Document;
075: import org.dom4j.Element;
076:
077: /**
078: * <a href="EditServerAction.java.html"><b><i>View Source</i></b></a>
079: *
080: * @author Brian Wing Shun Chan
081: *
082: */
083: public class EditServerAction extends PortletAction {
084:
085: public void processAction(ActionMapping mapping, ActionForm form,
086: PortletConfig config, ActionRequest req, ActionResponse res)
087: throws Exception {
088:
089: ThemeDisplay themeDisplay = (ThemeDisplay) req
090: .getAttribute(WebKeys.THEME_DISPLAY);
091:
092: PermissionChecker permissionChecker = themeDisplay
093: .getPermissionChecker();
094:
095: if (!permissionChecker.isOmniadmin()) {
096: SessionErrors.add(req, PrincipalException.class.getName());
097:
098: setForward(req, "portlet.admin.error");
099:
100: return;
101: }
102:
103: PortletPreferences prefs = PrefsPropsUtil.getPreferences();
104:
105: String cmd = ParamUtil.getString(req, Constants.CMD);
106:
107: if (cmd.equals("addLogLevel")) {
108: addLogLevel(req);
109: } else if (cmd.equals("cacheDb")) {
110: cacheDb();
111: } else if (cmd.equals("cacheMulti")) {
112: cacheMulti();
113: } else if (cmd.equals("cacheSingle")) {
114: cacheSingle();
115: } else if (cmd.equals("gc")) {
116: gc();
117: } else if (cmd.equals("precompile")) {
118: precompile(req, res);
119: } else if (cmd.equals("reIndex")) {
120: reIndex();
121: } else if (cmd.equals("shutdown")) {
122: shutdown(req);
123: } else if (cmd.equals("threadDump")) {
124: threadDump();
125: } else if (cmd.equals("updateLogLevels")) {
126: updateLogLevels(req);
127: } else if (cmd.equals("updateOpenOffice")) {
128: updateOpenOffice(req, prefs);
129: }
130:
131: sendRedirect(req, res);
132: }
133:
134: protected void addLogLevel(ActionRequest req) throws Exception {
135: String loggerName = ParamUtil.getString(req, "loggerName");
136: String priority = ParamUtil.getString(req, "priority");
137:
138: Logger logger = Logger.getLogger(loggerName);
139:
140: logger.setLevel(Level.toLevel(priority));
141: }
142:
143: protected void cacheDb() throws Exception {
144: CacheRegistry.clear();
145: }
146:
147: protected void cacheMulti() throws Exception {
148: MultiVMPoolUtil.clear();
149: }
150:
151: protected void cacheSingle() throws Exception {
152: LastModifiedCSS.clear();
153: LastModifiedJavaScript.clear();
154: WebCachePoolUtil.clear();
155: }
156:
157: protected void gc() throws Exception {
158: Runtime.getRuntime().gc();
159: }
160:
161: protected void jvm4ThreadDump(StringBuffer sb, ThreadGroup group) {
162: Thread[] threads = new Thread[group.activeCount()];
163:
164: group.enumerate(threads, false);
165:
166: for (int i = 0; i < threads.length && threads[i] != null; i++) {
167: Thread thread = threads[i];
168:
169: sb.append(StringPool.QUOTE);
170: sb.append(thread.getName());
171: sb.append(StringPool.QUOTE);
172:
173: if (thread.getThreadGroup() != null) {
174: sb.append(StringPool.SPACE);
175: sb.append(StringPool.OPEN_PARENTHESIS);
176: sb.append(thread.getThreadGroup().getName());
177: sb.append(StringPool.CLOSE_PARENTHESIS);
178: }
179:
180: sb.append(", priority=" + thread.getPriority());
181: sb.append("\n");
182: }
183:
184: ThreadGroup[] groups = new ThreadGroup[group.activeGroupCount()];
185:
186: group.enumerate(groups, false);
187:
188: for (int i = 0; i < groups.length && groups[i] != null; i++) {
189: jvm4ThreadDump(sb, groups[i]);
190: }
191: }
192:
193: protected void precompile(ActionRequest req, ActionResponse res)
194: throws Exception {
195:
196: Set jsps = new TreeSet();
197:
198: ServletContext ctx = (ServletContext) req
199: .getAttribute(WebKeys.CTX);
200:
201: // Struts
202:
203: Document doc = PortalUtil.readDocumentFromStream(ctx
204: .getResourceAsStream("/WEB-INF/struts-config.xml"));
205:
206: Element root = doc.getRootElement();
207:
208: Iterator itr1 = root.element("global-forwards").elements(
209: "forward").iterator();
210:
211: while (itr1.hasNext()) {
212: Element action = (Element) itr1.next();
213:
214: String fileName = action.attributeValue("path");
215:
216: if ((Validator.isNotNull(fileName))
217: && (fileName.endsWith(".jsp"))) {
218:
219: jsps.add(fileName);
220: }
221: }
222:
223: itr1 = root.element("action-mappings").elements("action")
224: .iterator();
225:
226: while (itr1.hasNext()) {
227: Element action = (Element) itr1.next();
228:
229: String fileName = action.attributeValue("forward");
230:
231: if ((Validator.isNotNull(fileName))
232: && (fileName.endsWith(".jsp"))) {
233:
234: jsps.add(fileName);
235: } else {
236: Iterator itr2 = action.elements("forward").iterator();
237:
238: while (itr2.hasNext()) {
239: Element forward = (Element) itr2.next();
240:
241: fileName = forward.attributeValue("path");
242:
243: if ((Validator.isNotNull(fileName))
244: && (fileName.endsWith(".jsp"))) {
245:
246: jsps.add(fileName);
247: }
248: }
249: }
250: }
251:
252: // Tiles
253:
254: doc = PortalUtil.readDocumentFromStream(ctx
255: .getResourceAsStream("/WEB-INF/tiles-defs.xml"));
256:
257: root = doc.getRootElement();
258:
259: itr1 = root.elements("definition").iterator();
260:
261: while (itr1.hasNext()) {
262: Element definition = (Element) itr1.next();
263:
264: String fileName = definition.attributeValue("path");
265:
266: if ((Validator.isNotNull(fileName))
267: && (fileName.endsWith(".jsp"))) {
268:
269: jsps.add(fileName);
270: } else {
271: Iterator itr2 = definition.elements("put").iterator();
272:
273: while (itr2.hasNext()) {
274: Element put = (Element) itr2.next();
275:
276: fileName = put.attributeValue("value");
277:
278: if ((Validator.isNotNull(fileName))
279: && (fileName.endsWith(".jsp"))) {
280:
281: jsps.add(fileName);
282: }
283: }
284: }
285: }
286:
287: // Precompile JSPs
288:
289: HttpServletRequest httpReq = PortalUtil
290: .getHttpServletRequest(req);
291: HttpServletResponse httpRes = new NullServletResponse(
292: PortalUtil.getHttpServletResponse(res));
293:
294: itr1 = jsps.iterator();
295:
296: while (itr1.hasNext()) {
297: try {
298: String jsp = StrutsUtil.TEXT_HTML_DIR + itr1.next();
299:
300: RequestDispatcher rd = ctx.getRequestDispatcher(jsp);
301:
302: if (rd != null) {
303: if (_log.isInfoEnabled()) {
304: _log.info("Precompiling " + jsp);
305: }
306:
307: rd.include(httpReq, httpRes);
308: }
309: } catch (Exception e) {
310: _log.debug(e, e);
311: }
312: }
313: }
314:
315: protected void reIndex() throws Exception {
316: long[] companyIds = PortalInstances.getCompanyIds();
317:
318: for (int i = 0; i < companyIds.length; i++) {
319: long companyId = companyIds[i];
320:
321: try {
322: LuceneIndexer indexer = new LuceneIndexer(companyId);
323:
324: indexer.reIndex();
325: } catch (Exception e) {
326: _log.error(e, e);
327: }
328: }
329: }
330:
331: protected void shutdown(ActionRequest req) throws Exception {
332: long minutes = ParamUtil.getInteger(req, "minutes")
333: * Time.MINUTE;
334: String message = ParamUtil.getString(req, "message");
335:
336: if (minutes <= 0) {
337: ShutdownUtil.cancel();
338: } else {
339: ShutdownUtil.shutdown(minutes, message);
340: }
341: }
342:
343: protected void threadDump() throws Exception {
344: String jvm = System.getProperty("java.vm.name") + " "
345: + System.getProperty("java.vm.version");
346:
347: StringBuffer sb = null;
348:
349: try {
350: sb = new StringBuffer("Full thread dump " + jvm + "\n\n");
351:
352: Map stackTraces = (Map) PortalClassInvoker.invoke(
353: Thread.class.getName(), "getAllStackTraces", false);
354:
355: Class[] nullParams = new Class[] {};
356: Object[] nullArgs = new Object[] {};
357:
358: Method getId = Thread.class.getMethod("getId", nullParams);
359: Method getState = Thread.class.getMethod("getState",
360: nullParams);
361:
362: Iterator itr = stackTraces.keySet().iterator();
363:
364: while (itr.hasNext()) {
365: Thread thread = (Thread) itr.next();
366:
367: StackTraceElement[] elements = (StackTraceElement[]) stackTraces
368: .get(thread);
369:
370: sb.append(StringPool.QUOTE);
371: sb.append(thread.getName());
372: sb.append(StringPool.QUOTE);
373:
374: if (thread.getThreadGroup() != null) {
375: sb.append(StringPool.SPACE);
376: sb.append(StringPool.OPEN_PARENTHESIS);
377: sb.append(thread.getThreadGroup().getName());
378: sb.append(StringPool.CLOSE_PARENTHESIS);
379: }
380:
381: sb.append(", priority=" + thread.getPriority());
382: sb.append(", id=" + getId.invoke(thread, nullArgs));
383: sb.append(", state="
384: + getState.invoke(thread, nullArgs));
385: sb.append("\n");
386:
387: for (int i = 0; i < elements.length; i++) {
388: sb.append("\t" + elements[i] + "\n");
389: }
390:
391: sb.append("\n");
392: }
393: } catch (Exception e) {
394: ThreadGroup root = Thread.currentThread().getThreadGroup();
395:
396: while (root.getParent() != null) {
397: root = root.getParent();
398: }
399:
400: sb = new StringBuffer("Summarized thread dump " + jvm
401: + "\n\n");
402:
403: jvm4ThreadDump(sb, root);
404: }
405:
406: _log.info(sb.toString());
407: }
408:
409: protected void updateLogLevels(ActionRequest req) throws Exception {
410: Enumeration enu = req.getParameterNames();
411:
412: while (enu.hasMoreElements()) {
413: String name = (String) enu.nextElement();
414:
415: if (name.startsWith("logLevel")) {
416: String loggerName = name.substring(8, name.length());
417:
418: String priority = ParamUtil.getString(req, name,
419: Level.INFO.toString());
420:
421: Logger logger = Logger.getLogger(loggerName);
422:
423: logger.setLevel(Level.toLevel(priority));
424: }
425: }
426: }
427:
428: protected void updateOpenOffice(ActionRequest req,
429: PortletPreferences prefs) throws Exception {
430:
431: boolean enabled = ParamUtil.getBoolean(req, "enabled");
432: String host = ParamUtil.getString(req, "host");
433: int port = ParamUtil.getInteger(req, "port");
434:
435: prefs.setValue(PropsUtil.OPENOFFICE_SERVER_ENABLED, String
436: .valueOf(enabled));
437: prefs.setValue(PropsUtil.OPENOFFICE_SERVER_HOST, host);
438: prefs.setValue(PropsUtil.OPENOFFICE_SERVER_PORT, String
439: .valueOf(port));
440:
441: prefs.store();
442: }
443:
444: private static Log _log = LogFactory.getLog(EditServerAction.class);
445:
446: }
|