001: /*
002: * Coefficient - facilitates project based collaboration
003: * Copyright (C) 2003, Dylan Etkin, CSIR icomtek
004: * PO Box 395
005: * Pretoria 0001, RSA
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package za.org.coefficient.html;
021:
022: import za.org.coefficient.core.Constants;
023: import za.org.coefficient.core.Project;
024: import za.org.coefficient.interfaces.CoefficientContext;
025:
026: import java.io.IOException;
027: import java.io.PrintWriter;
028: import java.io.Serializable;
029:
030: import java.util.ArrayList;
031: import java.util.HashMap;
032: import java.util.Iterator;
033: import java.util.TreeMap;
034:
035: import javax.naming.Context;
036: import javax.naming.NamingException;
037:
038: import za.org.coefficient.util.common.InvokerFactory;
039:
040: /**
041: * The Page object is like a sheet of paper on which the content is added.
042: * The theme is like a set of color pens and other printing devices and
043: * the modules are what are added to the sheet of paper. Once
044: * everything is in place, the Page is sent to the web browser.
045: *
046: * The Page instance is created by the CoefficientServlet object and
047: * is passed along through the Coefficient Context to all modules.
048: *
049: * @see za.org.coefficient.servlet.CoefficientServlet CoefficientServlet
050: *
051: *
052: * @author <a href="mailto:detkin@csir.co.za">Dylan Etkin</a>
053: * @version $Revision: 1.26 $
054: */
055: public class Page implements Serializable {
056: //~ Static fields/initializers =============================================
057:
058: private static final String JAVASCRIPT = "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"images?image=/calendar-win2k-cold-1.css\" title=\"win2k-cold-1\" />\n <script type=\"text/javascript\" src=\"images?image=/calendar.js\"></script>\n <script type=\"text/javascript\" src=\"images?image=/calendar-en.js\"></script>\n <script type=\"text/javascript\" src=\"images?image=/calendar-setup.js\"></script>\n <script language=\"Javascript\">\n<!--\nfunction render(t) {\nif (document.getElementById(t).style.display == \"none\") {\ndocument.getElementById(t).style.display=\"block\"\n} else {\ndocument.getElementById(t).style.display=\"none\"\n}\n}\n//-->\n</script>";
059: private static final String SIDE_WRAP_1 = "<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td><br><a style=\"color:blue;cursor:hand;FONT-FAMILY: Verdana;FONT-SIZE: 14px;\" name=\"";
060: private static final String SIDE_WRAP_2 = "\" onClick=\"render('";
061: private static final String SIDE_WRAP_3 = "')\">+/-</a></td></tr></table><table id=\"";
062: private static final String SIDE_WRAP_4 = "\" style=\"display:block\" width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" ><tr><td width=\"100%\">";
063: private static final String SIDE_WRAP_5 = "</td></tr></table>";
064: private static final String NAV_BLOCK_1 = "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" >\n<tr>\n<td class=\"navBlock\">\n";
065: //"<table width=\"100%\">\n<tr>\n<td class=\"navBlock\">\n";
066: private static final String NAV_BLOCK_2 = "\n</td>\n</tr>\n<tr><td>";
067: private static final String NAV_BLOCK_3 = "\n<br></td></tr></table>";
068:
069: //~ Instance fields ========================================================
070:
071: private CoefficientContext context = null;
072: private ArrayList errors;
073: private Project project = null;
074:
075: /** The theme used to render the page. */
076: private String theme = null;
077: private TreeMap centerContent = new TreeMap();
078: private HashMap centerModulePositions = new HashMap();
079: private TreeMap eastContent = new TreeMap();
080: private HashMap eastModulePositions = new HashMap();
081: private TreeMap northContent = new TreeMap();
082: private HashMap northModulePositions = new HashMap();
083: private TreeMap southContent = new TreeMap();
084: private HashMap southModulePositions = new HashMap();
085: private TreeMap westContent = new TreeMap();
086: private HashMap westModulePositions = new HashMap();
087: private int centerContentMax = Integer.MAX_VALUE;
088: private int eastContentMax = Integer.MAX_VALUE;
089: private int northContentMax = Integer.MAX_VALUE;
090: private int southContentMax = Integer.MAX_VALUE;
091: private int westContentMax = Integer.MAX_VALUE;
092:
093: //~ Constructors ===========================================================
094: //
095:
096: /**
097: * Constructor. The constructor just store the stream this page will
098: * write to.
099: */
100: public Page() {
101: errors = new ArrayList();
102: }
103:
104: public Page(CoefficientContext ctx) {
105: errors = new ArrayList();
106: context = ctx;
107: theme = determineTheme();
108: project = ctx.getProject();
109: }
110:
111: //~ Methods ================================================================
112:
113: public Project getProject() {
114: return project;
115: }
116:
117: public String getCenter() throws Exception {
118: StringBuffer sb = new StringBuffer("");
119: //sb.append("<td width=\"");
120:
121: Object[] params = { this };
122: sb.append("<td width=\"");
123: sb.append((String) InvokerFactory.getRemoteInvoker()
124: .invokeMethodOnTheme(theme, "getCenterPercentage",
125: params));
126: sb.append("\" valign=\"top\" >");
127: sb.append(getErrors());
128: sb.append((String) InvokerFactory.getRemoteInvoker()
129: .invokeMethodOnTheme(theme, "getCenter", params));
130: sb.append("</td>");
131:
132: return sb.toString();
133: }
134:
135: public void setCenterContent(String html, Integer position,
136: String moduleName) {
137: if (position == null) {
138: position = new Integer(centerContentMax);
139: centerContentMax--;
140: }
141: this .centerContent.put(position, html);
142: this .centerModulePositions.put(moduleName, position);
143: }
144:
145: public String getCenterContent() {
146: return getCenterContent(false);
147: }
148:
149: public String getCenterContent(boolean includeNavBlock) {
150: StringBuffer sb = new StringBuffer();
151: for (Iterator it = centerContent.keySet().iterator(); it
152: .hasNext();) {
153: Integer key = (Integer) it.next();
154: String moduleName = null;
155: for (Iterator itr = centerModulePositions.keySet()
156: .iterator(); itr.hasNext();) {
157: String key2 = (String) itr.next();
158: Integer value = (Integer) centerModulePositions
159: .get(key2);
160: if (value.equals(key)) {
161: moduleName = key2;
162: break;
163: }
164: }
165: String content = (String) centerContent.get(key);
166: if (includeNavBlock && !content.trim().equals("")
167: && moduleName != null
168: && !"".equals(moduleName.trim())) {
169: sb.append(NAV_BLOCK_1);
170: sb.append(moduleName);
171: sb.append(NAV_BLOCK_2);
172: sb.append(content);
173: sb.append(NAV_BLOCK_3);
174: } else {
175: sb.append(content);
176: }
177: }
178:
179: return sb.toString();
180: }
181:
182: public String getEast() throws Exception {
183: StringBuffer sb = new StringBuffer("");
184: Object[] params = { this };
185: /*
186: sb.append("<td width=\"");
187: sb.append((String)InvokerFactory.getRemoteInvoker().invokeMethodOnTheme(theme, "getEastPercentage", params));
188: sb.append("\" class=\"line2\" valign=\"top\" bgcolor=\"");
189: sb.append((String)InvokerFactory.getRemoteInvoker().invokeMethodOnTheme(theme, "getEastBackGround", params));
190: sb.append("\">\n");
191: */
192: sb.append((String) InvokerFactory.getRemoteInvoker()
193: .invokeMethodOnTheme(theme, "getEast", params));
194: /*
195: sb.append("</td>\n");
196: */
197:
198: return sb.toString();
199: }
200:
201: public void setEastContent(String html, Integer position,
202: String moduleName) {
203: if (position == null) {
204: position = new Integer(eastContentMax);
205: eastContentMax--;
206: }
207: this .eastContent.put(position, html);
208: this .eastModulePositions.put(moduleName, position);
209: }
210:
211: public String getEastContent() {
212: return getEastContent(true);
213: }
214:
215: public String getEastContent(boolean includeNavBlock) {
216: StringBuffer sb = new StringBuffer();
217: for (Iterator it = eastContent.keySet().iterator(); it
218: .hasNext();) {
219: Integer key = (Integer) it.next();
220: String moduleName = null;
221: for (Iterator itr = eastModulePositions.keySet().iterator(); itr
222: .hasNext();) {
223: String key2 = (String) itr.next();
224: Integer value = (Integer) eastModulePositions.get(key2);
225: if (value.equals(key)) {
226: moduleName = key2;
227: break;
228: }
229: }
230: String content = (String) eastContent.get(key);
231: if (includeNavBlock && !content.trim().equals("")
232: && moduleName != null
233: && !"".equals(moduleName.trim())) {
234: sb.append(NAV_BLOCK_1);
235: sb.append(moduleName);
236: sb.append(NAV_BLOCK_2);
237: sb.append(content);
238: sb.append(NAV_BLOCK_3);
239: } else {
240: sb.append(content);
241: }
242: }
243:
244: return sb.toString();
245: }
246:
247: public void setError(String html) {
248: this .errors.add("<font color=\"red\">" + html + "</font>");
249: }
250:
251: public String getErrors() {
252: StringBuffer sb = new StringBuffer("");
253: for (Iterator it = errors.iterator(); it.hasNext();) {
254: String error = (String) it.next();
255: sb.append("<li>" + error + "</li><br>");
256: }
257:
258: return sb.toString();
259: }
260:
261: public String getFooter() throws Exception {
262: StringBuffer sb = new StringBuffer("");
263: Object[] params = { this };
264: sb.append((String) InvokerFactory.getRemoteInvoker()
265: .invokeMethodOnTheme(theme, "getFooter", params));
266: sb.append("</body>\n</html>\n");
267:
268: return sb.toString();
269: }
270:
271: public String getHeader() throws Exception {
272: StringBuffer sb = new StringBuffer("");
273: Object[] params = { this };
274: sb.append((String) InvokerFactory.getRemoteInvoker()
275: .invokeMethodOnTheme(theme, "getHeader", params));
276: sb.append(JAVASCRIPT);
277:
278: return sb.toString();
279: }
280:
281: public void setModuleContent(String html, String name)
282: throws Exception {
283: this .setModuleContent(html, name, null);
284: }
285:
286: public void setModuleContent(String html, String name,
287: String utilityTheme) throws Exception {
288: Object[] params = { this , name, html };
289: if (utilityTheme == null) {
290: InvokerFactory.getRemoteInvoker().invokeMethodOnTheme(
291: theme, "format", params);
292: } else {
293: try {
294: Context initialContext = za.org.coefficient.util.common.ContextUtil
295: .getContext();
296: if (initialContext.lookup(Constants.JNDI_CONTEXT + "/"
297: + "utilityThemes" + "/" + utilityTheme) != null) {
298: InvokerFactory.getRemoteInvoker()
299: .invokeMethodOnTheme(utilityTheme,
300: "format", params);
301: theme = utilityTheme;
302: }
303: } catch (NamingException ne) {
304: ne.printStackTrace();
305: }
306: }
307: }
308:
309: public String getNorth() throws Exception {
310: Object[] params = { this };
311: StringBuffer sb = new StringBuffer("");
312: sb.append("<table width=\"");
313: sb.append((String) InvokerFactory.getRemoteInvoker()
314: .invokeMethodOnTheme(theme, "getTableWidth", params));
315: sb.append("\" border=\"0\" cellspacing=\"");
316: sb.append((String) InvokerFactory.getRemoteInvoker()
317: .invokeMethodOnTheme(theme, "getCellSpacing", params));
318: sb.append("\"");
319: sb.append(" cellpadding=\"");
320: sb.append((String) InvokerFactory.getRemoteInvoker()
321: .invokeMethodOnTheme(theme, "getCellPadding", params));
322: sb.append("\" bgcolor=\"");
323: sb.append((String) InvokerFactory.getRemoteInvoker()
324: .invokeMethodOnTheme(theme, "getNorthBackGround",
325: params));
326: sb.append("\">");
327: sb.append("<tr><td>");
328: sb.append((String) InvokerFactory.getRemoteInvoker()
329: .invokeMethodOnTheme(theme, "getNorth", params));
330:
331: return sb.toString();
332: }
333:
334: public void setNorthContent(String html, Integer position,
335: String moduleName) {
336: if (position == null) {
337: position = new Integer(northContentMax);
338: northContentMax--;
339: }
340: this .northContent.put(position, html);
341: this .northModulePositions.put(moduleName, position);
342: }
343:
344: public String getNorthContent() {
345: return getNorthContent(false);
346: }
347:
348: public String getNorthContent(boolean includeNavBlock) {
349: StringBuffer sb = new StringBuffer();
350: for (Iterator it = northContent.keySet().iterator(); it
351: .hasNext();) {
352: Integer key = (Integer) it.next();
353: String moduleName = null;
354: for (Iterator itr = northModulePositions.keySet()
355: .iterator(); itr.hasNext();) {
356: String key2 = (String) itr.next();
357: Integer value = (Integer) northModulePositions
358: .get(key2);
359: if (value.equals(key)) {
360: moduleName = key2;
361: break;
362: }
363: }
364: String content = (String) northContent.get(key);
365: if (includeNavBlock && !content.trim().equals("")
366: && moduleName != null
367: && !"".equals(moduleName.trim())) {
368: sb.append(NAV_BLOCK_1);
369: sb.append(moduleName);
370: sb.append(NAV_BLOCK_2);
371: sb.append(content);
372: sb.append(NAV_BLOCK_3);
373: } else {
374: sb.append(content);
375: }
376: }
377: return sb.toString();
378: }
379:
380: public String getSouth() throws Exception {
381: Object[] params = { this };
382: StringBuffer sb = new StringBuffer("");
383: sb.append((String) InvokerFactory.getRemoteInvoker()
384: .invokeMethodOnTheme(theme, "getSouth", params));
385:
386: return sb.toString();
387: }
388:
389: public void setSouthContent(String html, Integer position,
390: String moduleName) {
391: if (position == null) {
392: position = new Integer(southContentMax);
393: southContentMax--;
394: }
395: this .southContent.put(position, html);
396: this .southModulePositions.put(moduleName, position);
397: }
398:
399: public String getSouthContent() {
400: return getSouthContent(false);
401: }
402:
403: public String getSouthContent(boolean includeNavBlock) {
404: StringBuffer sb = new StringBuffer();
405: for (Iterator it = southContent.keySet().iterator(); it
406: .hasNext();) {
407: Integer key = (Integer) it.next();
408: String moduleName = null;
409: for (Iterator itr = southModulePositions.keySet()
410: .iterator(); itr.hasNext();) {
411: String key2 = (String) itr.next();
412: Integer value = (Integer) southModulePositions
413: .get(key2);
414: if (value.equals(key)) {
415: moduleName = key2;
416: break;
417: }
418: }
419: String content = (String) southContent.get(key);
420: if (includeNavBlock && !content.trim().equals("")
421: && moduleName != null
422: && !"".equals(moduleName.trim())) {
423: sb.append(NAV_BLOCK_1);
424: sb.append(moduleName);
425: sb.append(NAV_BLOCK_2);
426: sb.append(content);
427: sb.append(NAV_BLOCK_3);
428: } else {
429: sb.append(content);
430: }
431: }
432: return sb.toString();
433: }
434:
435: public String getThemeWelcomeContent() throws Exception {
436: return (String) InvokerFactory.getRemoteInvoker()
437: .invokeMethodOnTheme(theme, "getWelcomePageContent",
438: null);
439: }
440:
441: public String getWest() throws Exception {
442: StringBuffer sb = new StringBuffer("");
443: sb.append("<!--here-->\n<tr bgcolor=\"#FFFFFF\">");
444: Object[] params = { this };
445: sb.append((String) InvokerFactory.getRemoteInvoker()
446: .invokeMethodOnTheme(theme, "getWest", params));
447: return sb.toString();
448: }
449:
450: public void setWestContent(String html, Integer position,
451: String moduleName) {
452: if (position == null) {
453: position = new Integer(westContentMax);
454: westContentMax--;
455: }
456: this .westContent.put(position, html);
457: this .westModulePositions.put(moduleName, position);
458: }
459:
460: public String getWestContent() {
461: return getWestContent(true);
462: }
463:
464: public String getWestContent(boolean includeNavBlock) {
465: StringBuffer sb = new StringBuffer();
466: for (Iterator it = westContent.keySet().iterator(); it
467: .hasNext();) {
468: Integer key = (Integer) it.next();
469: String moduleName = null;
470: for (Iterator itr = westModulePositions.keySet().iterator(); itr
471: .hasNext();) {
472: String key2 = (String) itr.next();
473: Integer value = (Integer) westModulePositions.get(key2);
474: if (value.equals(key)) {
475: moduleName = key2;
476: break;
477: }
478: }
479: String content = (String) westContent.get(key);
480: if (includeNavBlock && !content.trim().equals("")
481: && moduleName != null
482: && !"".equals(moduleName.trim())) {
483: sb.append(NAV_BLOCK_1);
484: sb.append(moduleName);
485: sb.append(NAV_BLOCK_2);
486: sb.append(content);
487: sb.append(NAV_BLOCK_3);
488: } else {
489: sb.append(content);
490: }
491: }
492: return sb.toString();
493: }
494:
495: public String displayFootMessage() {
496: StringBuffer sb = new StringBuffer("");
497: sb.append("<font class=\"pn-sub\">\n${config:"
498: + Constants.CFG_FOOT1 + "}<br>\n</font>\n");
499:
500: return sb.toString();
501: }
502:
503: public long process(PrintWriter out) throws IOException, Exception {
504: long time = -System.currentTimeMillis();
505:
506: // this is just a special case when the user is generating
507: // print content that the project link is not on the page
508: //
509: if (theme != null && theme.indexOf("PrinterUtil") == -1) {
510: out.println(getHeader());
511: out.println(getNorth());
512: out.println(getWest());
513: out.println(getCenter());
514: out.println(getEast());
515: out.println(getSouth());
516: out.println(getFooter());
517: } else {
518: out.println(getCenterContent());
519: }
520:
521: time += System.currentTimeMillis();
522:
523: return time;
524: }
525:
526: /**
527: * This method can be used to clear a modules set content from the
528: * page before it has been rendered. The content is returned so you
529: * can do what you would like with the content but it will not show
530: * up in the page unless placed there manually.
531: *
532: * @param moduleName is the name of the modules content to clear.
533: * @return is the content html string if content has been set for the
534: * module, null otherwise.
535: */
536: public String clearModuleContent(String moduleName) {
537: // Search through the content holders for the module
538: Integer position = (Integer) centerModulePositions
539: .get(moduleName);
540: if (position != null) {
541: centerModulePositions.remove(moduleName);
542: return (String) centerContent.remove(position);
543: }
544: position = (Integer) eastModulePositions.get(moduleName);
545: if (position != null) {
546: eastModulePositions.remove(moduleName);
547: return (String) eastContent.remove(position);
548: }
549: position = (Integer) westModulePositions.get(moduleName);
550: if (position != null) {
551: westModulePositions.remove(moduleName);
552: return (String) westContent.remove(position);
553: }
554: position = (Integer) northModulePositions.get(moduleName);
555: if (position != null) {
556: northModulePositions.remove(moduleName);
557: return (String) northContent.remove(position);
558: }
559: position = (Integer) southModulePositions.get(moduleName);
560: if (position != null) {
561: southModulePositions.remove(moduleName);
562: return (String) southContent.remove(position);
563: }
564: return null;
565: }
566:
567: public String getPositionForModule(String moduleName) {
568: Object[] params = { moduleName };
569: try {
570: return (String) InvokerFactory.getRemoteInvoker()
571: .invokeMethodOnTheme(theme, "getPositionForModule",
572: params);
573: } catch (Exception e) {
574: return Theme.NULL_POSITION;
575: }
576: }
577:
578: private String determineTheme() {
579: if (context == null) {
580: return ThemeSupport.getCurrentThemeLocalName();
581: } else {
582: String t = context.getTheme();
583: if (t == null
584: || t
585: .equals(ThemeSupport
586: .getCurrentThemeLocalName())) {
587: if (context.getProject() != null) {
588: String projectTheme = context.getProject()
589: .getThemeName();
590: if (projectTheme != null
591: && !projectTheme.trim().equals(""))
592: return projectTheme;
593: else
594: return ThemeSupport.getCurrentThemeLocalName();
595: } else {
596: return ThemeSupport.getCurrentThemeLocalName();
597: }
598: } else {
599: return t;
600: }
601: }
602: }
603: }
|