001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.webadmin;
017:
018: import org.apache.openejb.loader.SystemInstance;
019: import org.apache.openejb.spi.ContainerSystem;
020: import org.apache.openejb.util.OpenEjbVersion;
021:
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.io.PrintWriter;
025: import java.net.URL;
026: import java.util.ArrayList;
027: import java.util.HashMap;
028: import java.util.Map;
029:
030: import javax.ejb.CreateException;
031: import javax.ejb.SessionContext;
032: import javax.naming.Context;
033: import javax.naming.NameClassPair;
034: import javax.naming.NamingEnumeration;
035:
036: /** This is the template web admin bean to extend from. It contains all the functionality for the webadministration. To use
037: * this class, simply sub-class it:<br><br>
038: *
039: * <code>
040: * public class MyBean extends WebAdminBean {
041: * ...
042: * }
043: * </code>
044: * <br><br>
045: * and declare the following methods:<br><br>
046: *
047: * <code>
048: * public void ejbCreate() {}<br>
049: * public void preProcess(HttpRequest request, HttpResponse response) throws IOException {}<br>
050: * public void postProcess(HttpRequest request, HttpResponse response) throws IOException {}<br>
051: * public void writeBody(PrintWriter body) throws IOException {}<br>
052: * public void writeHtmlTitle(PrintWriter body) throws IOException {}<br>
053: * public void writePageTitle(PrintWriter body) throws IOException {}<br>
054: * public void writeSubMenuItems(PrintWriter body) throws IOException {}<br>
055: * </code>
056: *
057: * @author <a href="mailto:david.blevins@visi.com">David Blevins</a>
058: * @author <a href="mailto:tim_urberg@yahoo.com">Tim Urberg</a>
059: */
060: public abstract class WebAdminBean implements HttpBean {
061: /** used for the session context
062: */
063: protected SessionContext ejbContext;
064: /** the substitue
065: */
066: public static final int SUBSTITUTE = 26;
067: /** the navigation sections
068: */
069: public static HashMap sections;
070: /** the menu section
071: */
072: protected String section = "";
073: /** the HTTP request
074: */
075: protected HttpRequest request;
076: /** the HTTP response
077: */
078: protected HttpResponse response;
079: /** the standard title */
080: public static final String HTML_TITLE = "OpenEJB Web Administration Console";
081:
082: /** the main method of this bean, it takes care of the processing
083: * @param request the http request
084: * @param response the http response
085: * @throws IOException if an exception is thrown
086: */
087: public void onMessage(HttpRequest request, HttpResponse response)
088: throws IOException {
089: this .request = request;
090: this .response = response;
091:
092: preProcess(request, response);
093:
094: // Assuming things are good
095: java.io.PrintWriter body = response.getPrintWriter();
096: InputStream template = getTemplate();
097:
098: // Write till PAGETITLE
099: writeTemplate(body, template);
100: writeHtmlTitle(body);
101:
102: // Write till TOP_NAV_BAR
103: writeTemplate(body, template);
104: writeTopNavBar(body);
105:
106: // Write till LEFT_NAV_BAR
107: writeTemplate(body, template);
108: writeLeftNavBar(body);
109:
110: // Write till TITLE
111: writeTemplate(body, template);
112: writePageTitle(body);
113:
114: // Write till BODY
115: writeTemplate(body, template);
116: writeBody(body);
117:
118: // Write till FOOTER
119: writeTemplate(body, template);
120: writeFooter(body);
121:
122: // Write the rest
123: writeTemplate(body, template);
124: postProcess(request, response);
125: }
126:
127: /** called before any content is written to the browser
128: * @param request the http request
129: * @param response the http response
130: * @throws IOException if an exception is thrown
131: */
132: public abstract void preProcess(HttpRequest request,
133: HttpResponse response) throws IOException;
134:
135: /** called after all content is written to the browser
136: * @param request the http request
137: * @param response the http response
138: * @throws IOException if an exception is thrown
139: */
140: public abstract void postProcess(HttpRequest request,
141: HttpResponse response) throws IOException;
142:
143: /** Write the TITLE of the HTML document. This is the part
144: * that goes into the <code><head><title>
145: * </title></head></code> tags
146: *
147: * @param body the output to write to
148: * @exception IOException of an exception is thrown
149: *
150: */
151: public abstract void writeHtmlTitle(PrintWriter body)
152: throws IOException;
153:
154: /** Write the title of the page. This is displayed right
155: * above the main block of content.
156: *
157: * @param body the output to write to
158: * @exception IOException if an exception is thrown
159: */
160: public abstract void writePageTitle(PrintWriter body)
161: throws IOException;
162:
163: /** Write the top navigation bar of the page. This should look somthing
164: * like the one below:
165: *
166: * <code>
167: * <a href="system?show=server">
168: * <span class="menuTopOff">Remote Server</span>
169: * </a>
170: * <a href="system?show=containers">
171: * <span class="menuTopOff">Containers</span>
172: * </a>
173: * <a href="system?show=deployments">
174: * <span class="menuTopOff">Deployments</span>
175: * </a>
176: * <a href="system?show=logs">
177: * <span class="menuTopOff">Logs</span>
178: * </a>
179: * </code>
180: *
181: * @param body the output to write to
182: * @exception IOException if an exception is thrown
183: */
184: public void writeTopNavBar(PrintWriter body) throws IOException {
185: // for (int i=0; i < navSections.length; i+=2){
186: // body.print("<a href=\"");
187: // body.print(navSections[i]);
188: // body.print("\" class=\"menuTopOff\">");
189: // body.print(navSections[i+1]);
190: // if(i == (navSections.length-2))
191: // body.print("</a>");
192: // else
193: // body.print("</a> | ");
194: // }
195: }
196:
197: /** Write the left navigation bar of the page. This should look somthing
198: * like the one below:
199: *
200: * <code>
201: * <tr>
202: * <td valign="top" align="left">
203: * <span class="subMenuOn">
204: * Admin
205: * </span>
206: * </td>
207: * </tr>
208: * <tr>
209: * <td valign="top" align="left">
210: * <a href="system?show=status"><span class="subMenuOff">
211: * Status
212: * </span>
213: * </a></td>
214: * </tr>
215: * <tr>
216: * <<td valign="top" align="left">
217: * <a href="system?show=deployments"><span class="subMenuOff">
218: * Deployments
219: * </span>
220: * </a></td>
221: * </tr>
222: * </code>
223: *
224: * @param body the output to write to
225: * @exception IOException if an exception is thrown
226: */
227: public void writeLeftNavBar(PrintWriter body) throws IOException {
228: Object[] entries = sections.entrySet().toArray();
229:
230: for (int i = 0; i < entries.length; i++) {
231: Map.Entry entry = (Map.Entry) entries[i];
232: String section = (String) entry.getKey();
233: String[] subSections = (String[]) entry.getValue();
234:
235: body.println("<tr><td valign=\"top\" align=\"left\">");
236: body.print("<span class=\"subMenuOn\">");
237: body.print(section);
238: body.print("</td></tr>");
239:
240: for (int j = 0; j < subSections.length; j += 2) {
241: String name = subSections[j];
242: String url = subSections[j + 1];
243:
244: body.print("<tr>");
245: body.print("<td valign=\"top\" align=\"left\">");
246: body.print("<a href=\"/");
247: body.print(section);
248: body.print('/');
249: body.print(url);
250: body.print("\" class=\"subMenuOff\">");
251: body.print(" ");
252: body.print(name);
253: body.print("</a></td></tr>");
254: }
255: }
256: }
257:
258: /** formats a sub menu item for the left navigation
259: * @param itemName the name for display
260: * @param url the url to link
261: * @return the html that is formatted
262: */
263: public String formatSubMenuItem(String itemName, String url) {
264: StringBuffer buff = new StringBuffer();
265:
266: return buff.toString();
267: }
268:
269: /** writes the main body content to the broswer. This content is inside a <code><p></code> block
270: *
271: *
272: * @param body the output to write to
273: * @exception IOException if an exception is thrown
274: */
275: public abstract void writeBody(PrintWriter body) throws IOException;
276:
277: /** Write the footer
278: *
279: * @param body the output to write to
280: * @exception IOException if an exception is thrown
281: */
282: public void writeFooter(PrintWriter body) throws IOException {
283: body.print(footer);
284: }
285:
286: /** the footer
287: */
288: protected static String footer = getFooter();
289:
290: /** gets a footer for the document
291: * @return the footer string
292: */
293: public static String getFooter() {
294: StringBuffer out = new StringBuffer(100);
295:
296: OpenEjbVersion info = OpenEjbVersion.get();
297:
298: out.append("<a href=\"" + info.getUrl() + "\">OpenEJB</a> ");
299: out.append(info.getVersion() + "<br>");
300: out.append("build: " + info.getDate() + "-" + info.getTime());
301: return out.toString();
302: }
303:
304: /** writes a template from the input stream to the output stream
305: * @param out the output to write to
306: * @param template the template to read
307: * @throws IOException if an exception is thrown
308: */
309: public void writeTemplate(PrintWriter out, InputStream template)
310: throws IOException {
311: int b = template.read();
312: //System.out.println("[] read");
313: while (b != -1 && b != SUBSTITUTE) {
314: out.write(b);
315: b = template.read();
316: }
317: //System.out.println("[] done reading");
318: }
319:
320: /** gets an html template which is the content of the pages written to the browser
321: * @throws IOException if an exception is thrown
322: * @return the template
323: */
324: public InputStream getTemplate() throws IOException {
325: //System.out.println("[] get template");
326: // ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
327: ClassLoader classLoader = this .getClass().getClassLoader();
328: URL url = classLoader.getResource("/htdocs/template.html");
329: return url.openConnection().getInputStream();
330: }
331:
332: /** initalizes the left and top menu navigation
333: */
334: public HashMap initNavSections() {
335: HashMap sections = new HashMap();
336: try {
337: ContainerSystem containerSystem = SystemInstance.get()
338: .getComponent(ContainerSystem.class);
339: Context ctx = containerSystem.getJNDIContext();
340: ctx = (Context) ctx.lookup("openejb/ejb");
341: NamingEnumeration enumeration = ctx.list("");
342: //System.out.println("\n\nENUM "+enumeration);
343:
344: if (enumeration == null) {
345: return sections;
346: }
347:
348: while (enumeration.hasMore()) {
349: NameClassPair entry = (NameClassPair) enumeration
350: .next();
351: //System.out.println("ITEM NAME "+entry.getName());
352: //System.out.println("ITEM CLASS "+entry.getClassName());
353: if (!entry
354: .getClassName()
355: .equals(
356: "org.apache.openejb.core.ivm.naming.IvmContext")) {
357: continue;
358: }
359:
360: Context subCtx = (Context) ctx.lookup(entry.getName());
361: String[] subSections = getSubsections(subCtx);
362: if (subSections.length > 0) {
363: sections.put(entry.getName(), subSections);
364: }
365: }
366: } catch (Exception e) {
367: e.printStackTrace();
368: }
369: return sections;
370: }
371:
372: private String[] getSubsections(Context ctx) {
373: ArrayList sections = new ArrayList();
374: try {
375: NamingEnumeration enumeration = ctx.list("");
376:
377: if (enumeration == null) {
378: return new String[0];
379: }
380:
381: while (enumeration.hasMore()) {
382: NameClassPair entry = (NameClassPair) enumeration
383: .next();
384: //System.out.println("ITEM NAME "+entry.getName());
385: //System.out.println("ITEM CLASS "+entry.getClassName());
386: if (!entry
387: .getClassName()
388: .equals(
389: "org.apache.openejb.core.stateless.EncReference")) {
390: continue;
391: }
392:
393: if (entry.getName().startsWith("Default")) {
394: continue;
395: }
396:
397: Object obj = ctx.lookup(entry.getName());
398: if (obj instanceof HttpHome) {
399: String beanName = entry.getName();
400: sections.add(beanName);
401: sections.add(beanName);
402: }
403: }
404: } catch (Exception e) {
405: e.printStackTrace();
406: }
407: return (String[]) sections.toArray(new String[0]);
408: }
409:
410: /** prints a table row similar to this
411: *
412: * <tr>
413: * <td>some info</td>
414: * <td>some more info</td>
415: * </tr>
416: * @param col1 the first column
417: * @param col2 the second column
418: * @param out the output to write to
419: * @throws IOException if an exception is thrown
420: */
421: protected void printRow(String col1, String col2, PrintWriter out)
422: throws IOException {
423: out.println("<tr>");
424: out.print("<td class=\"bodyBlack\">");
425: out.print(col1);
426: out.println("</td>");
427: out.print("<td class=\"bodyBlack\">");
428: out.print(col2);
429: out.println("</td>");
430: out.println("</tr>");
431: }
432:
433: /** prints a table row similar to this
434: *
435: * <tr>
436: * <td>some info</td>
437: * <td>some more info</td>
438: * <td>yet some more info</td>
439: * </tr>
440: * @param col1 the first column
441: * @param col2 the second column
442: * @param col3 the third column
443: * @param out the output to write to
444: * @throws IOException if an exception is thrown
445: */
446: protected void printRow(String col1, String col2, String col3,
447: PrintWriter out) throws IOException {
448: out.println("<tr>");
449: out.print("<td class=\"bodyBlack\">");
450: out.print(col1);
451: out.println("</td>");
452: out.print("<td class=\"bodyBlack\">");
453: out.print(col2);
454: out.println("</td>");
455: out.print("<td class=\"bodyBlack\">");
456: out.print(col3);
457: out.println("</td>");
458: out.println("</tr>");
459: }
460:
461: /*---------------------------------------------------------------*/
462: /* EJB API Callbacks */
463: /*---------------------------------------------------------------*/
464: /** called with the bean is created
465: * @throws CreateException if the bean cannot be created
466: */
467: public void ejbCreate() throws CreateException {
468: }
469:
470: /** called on a stateful sessionbean after the bean is
471: * deserialized from storage and put back into use.
472: */
473: public void ejbActivate() {
474: }
475:
476: /** called on a stateful sessionbean before the bean is
477: * removed from memory and serialized to a temporary store.
478: * This method is never called on a stateless sessionbean
479: */
480: public void ejbPassivate() {
481: }
482:
483: /** called when the bean is about to be garbage collected
484: */
485: public void ejbRemove() {
486: }
487:
488: /** sets the session context
489: * @param sessionContext the session context
490: */
491: public void setSessionContext(SessionContext sessionContext) {
492: ejbContext = sessionContext;
493: if (sections == null) {
494: sections = initNavSections();
495: }
496: }
497: }
|