001: package com.salmonllc.html;
002:
003: /////////////////////////
004: //$Archive: /SOFIA/SourceCode/com/salmonllc/html/HtmlPageBase.java $
005: //$Author: Dan $
006: //$Revision: 40 $
007: //$Modtime: 9/22/04 10:15a $
008: /////////////////////////
009:
010: import com.salmonllc.localizer.LanguagePreferences;
011: import com.salmonllc.localizer.LanguageResourceFinder;
012: import com.salmonllc.portlet.PortletInfo;
013: import com.salmonllc.portlet.SalmonPortlet;
014: import com.salmonllc.properties.*;
015: import com.salmonllc.personalization.Skin;
016:
017: import javax.portlet.ActionRequest;
018: import javax.portlet.ActionResponse;
019: import javax.servlet.http.*;
020: import java.io.*;
021: import java.util.*;
022:
023: /**
024: * This abstract class is the base class for the HTMLPage and HTMLFrameset classes
025: */
026:
027: public abstract class HtmlPageBase implements Serializable {
028: private transient HttpServletRequestWrapper _currentReq;
029: private transient HttpServletResponseWrapper _currentRes;
030: private transient HttpSession _currentSession;
031: private String _pageName = null;
032: private String _applicationName = null;
033:
034: public static final int BROWSER_NETSCAPE = 0;
035: public static final int BROWSER_MICROSOFT = 1;
036: public static final int BROWSER_DREAMWEAVER = 2;
037:
038: public static final int BROWSER_OS_WINDOWS = 0;
039: public static final int BROWSER_OS_MAC = 1;
040: public static final int BROWSER_OS_OTHER = 2;
041:
042: private int _browserType = BROWSER_NETSCAPE;
043: private float _browserVersion = 4;
044: private int _browserOS = BROWSER_OS_WINDOWS;
045: private boolean _historyFixUp = false;
046: private boolean _sessionExpired = false;
047:
048: private boolean _generateFull = true;
049: protected String _subPageNameValue = null;
050: private boolean _disableRedirect = false;
051: private String _serverURL = null;
052:
053: private String _contentType = null;
054: public static final String APPLICATION_ALIAS_SESSION_KEY = "$ApplicationAlias$";
055: public static final String LANGUAGE_SESSION_KEY = "$SOFIALanguagePreferences$";
056:
057: private String _servletBaseURL = null;
058:
059: private String _origApplicationName = null;
060: private boolean _forwardPerformed = false;
061: protected boolean _useDisabledAttribute = true;
062: protected static final boolean debug = false;
063: private Skin _skin;
064: private PortletInfo _portletInfo;
065:
066: /**
067: * This method removes the current language preferneces so it will be reloaded on the next page hit
068: */
069: public void clearLanguagePreferences() {
070: getSession().removeAttribute(LANGUAGE_SESSION_KEY);
071: }
072:
073: /**
074: * This method will remove all instances the current page from the session. Future calls to the page will create and initialize a new page each time.
075: */
076: public void clearPageFromSession() {
077: clearPageFromSession(_pageName);
078: }
079:
080: /**
081: * This method will remove all instances of a page from the session. Future calls to the page will create and initialize a new page each time.
082: */
083: public void clearPageFromSession(String pageName) {
084:
085: String cName = getPageProperties().getProperty(
086: Props.SYS_APP_PACKAGE);
087: String app = getApplicationName();
088:
089: if (cName == null)
090: cName = app + "." + pageName;
091: else
092: cName += "." + app + "." + pageName;
093:
094: cName = "$page$" + cName;
095:
096: HttpSession sess = getSession();
097:
098: if (sess.getAttribute(cName) != null)
099: sess.removeAttribute(cName);
100:
101: int i = 0;
102: while (true) {
103: String name = cName + "_" + i;
104: if (sess.getAttribute(name) == null)
105: break;
106: sess.removeAttribute(name);
107: i++;
108: }
109: }
110:
111: /**
112: * Called By the framework if a call to the page results in an error. This method should not be called directly.
113: */
114: public static void displayError(String error, Exception e,
115: PrintWriter p) {
116: p.write("<HTML><HEAD></HEAD><BODY>");
117: p.write("<H1>" + error + "</H1><BR>");
118:
119: if (e instanceof java.sql.SQLException)
120: p
121: .write("<H2>The application is having trouble communicating with the database engine. Please notify your system administrator. Detailed error messages follow.</H2><BR><BR>");
122:
123: p.write(e.getMessage() + "<BR><BR>");
124:
125: try {
126: ByteArrayOutputStream out = new ByteArrayOutputStream();
127: PrintWriter pw = new PrintWriter(out);
128: e.printStackTrace(pw);
129: pw.close();
130: out.close();
131:
132: ByteArrayInputStream in = new ByteArrayInputStream(out
133: .toByteArray());
134: BufferedReader b = new BufferedReader(
135: new InputStreamReader(in));
136:
137: StringBuffer sb = new StringBuffer();
138: String line = b.readLine();
139: while (line != null) {
140: sb.setLength(0);
141: int count = 0;
142: for (int i = 0; i < line.length(); i++) {
143: char c = line.charAt(i);
144: if (c == '\t') {
145: sb.append("<BLOCKQUOTE>");
146: count++;
147: } else
148: sb.append(c);
149: }
150: for (int i = 0; i < count; i++)
151: sb.append("</BLOCKQUOTE>");
152: p.println(sb.toString());
153: line = b.readLine();
154: }
155: in.close();
156: } catch (Exception ex) {
157: }
158:
159: p.write("</BODY></HTML>");
160: }
161:
162: /**
163: * This method will generate the html for each component in the page
164: */
165: public abstract void generateHTML(PrintWriter p) throws Exception;
166:
167: /**
168: * This method gets the name of the application that the page is part of.
169: */
170: public String getApplicationName() {
171: return _applicationName;
172: }
173:
174: /**
175: * This method Returns the Operating System the browser is running in. Valid return values are BROWSER_OS_MICROSOFT, BROWSER_OS_MAC or BROWSER_OS_OTHER;
176: */
177: public int getBrowserOS() {
178: return _browserOS;
179: }
180:
181: /**
182: * This method was created in VisualAge.
183: * @return int
184: */
185: public float getBrowserSubVersion() {
186: return _browserVersion;
187: }
188:
189: /**
190: * This method Returns the Browser Type: BROWSER_NETSCAPE or BROWSER_MICROSOFT.
191: */
192: public int getBrowserType() {
193: return _browserType;
194: }
195:
196: /**
197: * This method was created in VisualAge.
198: * @return int
199: */
200: public int getBrowserVersion() {
201: return (int) _browserVersion;
202: }
203:
204: /**
205: * This method was created in VisualAge.
206: * @return java.lang.String
207: */
208: public String getContentType() {
209: return _contentType;
210: }
211:
212: /**
213: * This method gets the current HttpServletRequest for the page.
214: */
215: public HttpServletRequest getCurrentRequest() {
216: return _currentReq;
217: }
218:
219: /**
220: * This method gets the current HttpServletResponse for the page.
221: */
222: public HttpServletResponse getCurrentResponse() {
223: return _currentRes;
224: }
225:
226: /**
227: * This method was created in VisualAge.
228: * @return boolean
229: */
230: public boolean getDisableRedirect() {
231: return _disableRedirect;
232: }
233:
234: /**
235: * This method sets whether or not the page will generate full html. Setting the property to false will cause the page to only generate the html in the contained components and not any headers or footers.
236: */
237: public boolean getGenerateFullHTML() {
238: return _generateFull;
239: }
240:
241: /**
242: * This method gets whether or not the pages history fixup mechanism is enabled.
243: */
244: public boolean getHistoryFixUp() {
245: return _historyFixUp;
246: }
247:
248: /**
249: * This method returns the users language preference
250: */
251: public LanguagePreferences getLanguagePreferences() {
252: return (LanguagePreferences) getSession().getAttribute(
253: LANGUAGE_SESSION_KEY);
254: }
255:
256: /**
257: * This method returns the original name of the application if application alaising is used. In that case getApplicationName will return the name of the alias and getOrigApplication name will get the "real" name of the application. If aliasing isn't used, they will both return the same value.
258: */
259: public String getOrigApplicationName() {
260: return _origApplicationName;
261: }
262:
263: /**
264: * This method gets the name of the page.
265: */
266: public String getPageName() {
267: return _pageName;
268: }
269:
270: /**
271: * This method gets the current Properties Object (com.salmonllc.properties.props) associated with this page.
272: */
273: public Props getPageProperties() {
274: Props p = Props.getProps(_applicationName, _pageName);
275: Skin sk = getSkin();
276: if (sk != null)
277: p.setUnitProperties(sk.getProperties());
278: return p;
279: }
280:
281: /**
282: * This method gets the current url for the server that the page is running on.
283: */
284: public String getServerURL() {
285: return _serverURL;
286: }
287:
288: /**
289: * This method gets the base url for servlets in this environment from the server name up to but not including the servlet name.
290: */
291: public String getServletBaseURL() {
292: return _servletBaseURL;
293: }
294:
295: /**
296: * This method gets the path for the servlet that ran the page.
297: */
298: public String getServletPath() {
299: return _servletBaseURL + "/AppServer";
300: }
301:
302: /**
303: * This method gets the current HttpSession used by this page.
304: */
305: public HttpSession getSession() {
306: return _currentSession;
307: }
308:
309: /**
310: * If the user went to a subpage, this method will return the name of it.
311: */
312: public String getSubPageName() {
313: return _subPageNameValue;
314: }
315:
316: /**
317: * This method should be overridden in subclasses of the page class. In the method, HTML components should be created and placed in the page, listeners registered and any other initialization tasks should be performed.
318: */
319: public abstract void initialize() throws Exception;
320:
321: /**
322: * This method will indicate whether the session for the current page request is expired.
323: */
324: public boolean isSessionExpired() {
325: return _sessionExpired;
326: }
327:
328: /**
329: * Called By the framework when the page is created to load properties from property files. This method should not be called directly.
330: */
331: public void loadProperties() {
332:
333: }
334:
335: /**
336: * This method will process the parms from a post for every component in the page.
337: */
338: public abstract void processParms(boolean iFrameSubmit)
339: throws Exception;
340:
341: /**
342: * This method will set an alias for the current application for the current user session. Every page created in this application after this method is called will have its application name initialized to the specified alias name instead of the application name. This will cause the application to use a different property file to load page and component properties.
343: */
344: public void resetApplicationAlias() {
345: String path = getCurrentRequest().getPathInfo();
346: StringTokenizer t = new StringTokenizer(path, "/");
347: String app = t.nextToken();
348:
349: HttpSession sess = getSession();
350:
351: Object o = sess.getAttribute(APPLICATION_ALIAS_SESSION_KEY);
352:
353: if (o == null)
354: return;
355:
356: java.util.Hashtable h = (java.util.Hashtable) o;
357: h.remove(app);
358: sess.setAttribute(APPLICATION_ALIAS_SESSION_KEY, h);
359: }
360:
361: /**
362: * This method will set an alias for the current application for the current user session. Every page created in this application after this method is called will have its application name initialized to the specified alias name instead of the application name. This will cause the application to use a different property file to load page and component properties.
363: */
364: public void setApplicationAlias(String applicationAlias) {
365: String path = getCurrentRequest().getPathInfo();
366: StringTokenizer t = new StringTokenizer(path, "/");
367: String app = t.nextToken();
368:
369: HttpSession sess = getSession();
370:
371: Object o = sess.getAttribute(APPLICATION_ALIAS_SESSION_KEY);
372:
373: java.util.Hashtable h = (o == null ? new java.util.Hashtable()
374: : (java.util.Hashtable) o);
375: h.put(app, applicationAlias);
376: sess.setAttribute(APPLICATION_ALIAS_SESSION_KEY, h);
377: }
378:
379: public void setApplicationName(String name) {
380: _applicationName = name;
381: }
382:
383: /**
384: * Sets the mime type that this page will return to the browser
385: */
386: public void setContentType(String contentType) {
387: _contentType = contentType;
388: }
389:
390: /**
391: * Called By the framework to on each request to set the HttpServletRequest. This method should not be called directly.
392: */
393: public void setCurrentRequest(ActionRequest r) {
394: if (_currentReq == null)
395: _currentReq = new HttpServletRequestWrapper(r);
396: else
397: _currentReq.setRequest(r);
398: }
399:
400: /**
401: * Called By the framework to on each request to set the HttpServletRequest. This method should not be called directly.
402: */
403: public void setCurrentRequest(HttpServletRequest r) {
404: if (r instanceof HttpServletRequestWrapper)
405: _currentReq = (HttpServletRequestWrapper) r;
406: else if (_currentReq == null)
407: _currentReq = new HttpServletRequestWrapper(r);
408: else
409: _currentReq.setRequest(r);
410:
411: String userAgent = r.getHeader("user-agent");
412: _browserType = BROWSER_NETSCAPE;
413: _browserOS = BROWSER_OS_WINDOWS;
414: _browserVersion = 4;
415: if (userAgent != null) {
416: if (userAgent.indexOf("Windows") > -1)
417: _browserOS = BROWSER_OS_WINDOWS;
418: else if (userAgent.indexOf("Mac") > -1)
419: _browserOS = BROWSER_OS_MAC;
420: else
421: _browserOS = BROWSER_OS_OTHER;
422:
423: int pos = userAgent.indexOf("MSIE");
424: if (pos > -1) {
425: _browserType = BROWSER_MICROSOFT;
426: int pos2 = userAgent.indexOf(";", pos);
427: if (pos2 > -1)
428: userAgent = userAgent.substring(pos, pos2);
429:
430: pos = userAgent.indexOf(' ');
431: if (pos > -1) {
432: String ver = userAgent.substring(pos + 1);
433: try {
434: Float f = new Float(ver);
435: _browserVersion = f.floatValue();
436: } catch (Exception e) {
437: _browserVersion = 3;
438: }
439: }
440: } else if (userAgent.startsWith("Mozilla")) {
441: _browserType = BROWSER_NETSCAPE;
442:
443: //Search for Netscape version 7
444: int idxNS7 = userAgent.indexOf("Netscape/7");
445: if (idxNS7 > 0) { //version 7...
446: _browserVersion = 7;
447: } else {
448: pos = userAgent.indexOf(' ');
449: if (pos > -1)
450: userAgent = userAgent.substring(0, pos);
451:
452: pos = userAgent.indexOf('/');
453: if (pos > -1) {
454: String ver = userAgent.substring(pos + 1);
455: try {
456: Float f = new Float(ver);
457: _browserVersion = f.floatValue();
458: if (((int) _browserVersion) == 5)
459: _browserVersion++;
460: } catch (Exception e) {
461: _browserVersion = 3;
462: }
463: }
464: }
465: } else if (userAgent.equalsIgnoreCase("MMHttp")) {
466: _browserType = BROWSER_DREAMWEAVER;
467: _browserVersion = 6;
468: }
469:
470: }
471:
472: }
473:
474: /**
475: * Called By the framework to on each request to set the servlet response. This method should not be called directly.
476: */
477:
478: public void setCurrentResponse(HttpServletResponse r) {
479: if (r instanceof HttpServletResponseWrapper)
480: _currentRes = (HttpServletResponseWrapper) r;
481: else if (_currentRes == null
482: || _currentRes instanceof HttpServletResponseDummy)
483: _currentRes = new HttpServletResponseWrapper(r, this );
484: else
485: _currentRes.setResponse(r);
486: }
487:
488: /**
489: * Called By the framework to on each request to set the servlet response. This method should not be called directly.
490: */
491:
492: public void setCurrentResponse(ActionResponse res, ActionRequest req) {
493: if (_currentRes == null)
494: _currentRes = new HttpServletResponseWrapper(res, req, this );
495: else
496: _currentRes.setResponse(res, req);
497: }
498:
499: /**
500: * This method sets whether or not the page will do a redirect for each submit. The redirect prevents browsers from displaying a page expired message when the user clicks the back button.
501: * @param bRedirect boolean
502: */
503: public void setDisableRedirect(boolean bRedirect) {
504: _disableRedirect = bRedirect;
505: }
506:
507: /**
508: * This method sets whether or not the page will generate full html. Setting the property to false will cause the page to only generate the html in the contained components and not any headers or footers.
509: */
510: public void setGenerateFullHTML(boolean gen) {
511: _generateFull = gen;
512: }
513:
514: /**
515: * This method enables or disables the pages history fixup mechanism.
516: */
517: public void setHistoryFixUp(boolean ok) {
518: _historyFixUp = ok;
519: }
520:
521: /**
522: * Use this to override the language preferences sent by the browser
523: */
524: public void setLanguagePrefrence(LanguagePreferences pref) {
525: getSession().setAttribute(LANGUAGE_SESSION_KEY, pref);
526: }
527:
528: /**
529: * Called By the framework to on each request to set the Application Name. This method should not be called directly.
530: */
531:
532: public void setOrigApplicationName(String name) {
533: _origApplicationName = name;
534: }
535:
536: /**
537: * Called By the framework to on each request to set the page name. This method should not be called directly.
538: */
539:
540: public void setPageName(String name) {
541: _pageName = name;
542: }
543:
544: /**
545: * Called By the framework to on each request to set the Server's URL. This method should not be called directly.
546: */
547:
548: public void setServerURL(String url) {
549: _serverURL = url;
550: }
551:
552: /**
553: * Called By the framework to on each request to set the Base URL for the servlet. This method should not be called directly.
554: */
555: public void setServletBaseURL(String url) {
556: _servletBaseURL = url;
557: }
558:
559: /**
560: * Called By the framework to on each request to set the HttpSession. This method should not be called directly.
561: */
562:
563: public void setSession(HttpSession s) {
564: _currentSession = s;
565: }
566:
567: /**
568: * Called By the framework to on each request to set whether the session is expired. This method should not be called directly.
569: */
570: public void setSessionExpired(boolean exp) {
571: _sessionExpired = exp;
572: }
573:
574: /**
575: * Called By the framework to on each request to set the name of the subpage selected. This method should not be called directly.
576: */
577: public void setSubPageName(String name) {
578: _subPageNameValue = name;
579: }
580:
581: /**
582: * This method sets up the language prefrences for the page. This method should is called by the framework and should not be called directly
583: */
584: public void setUpLanguagePreferences() {
585: Props p = getPageProperties();
586: if (!p.getBooleanProperty(Props.LOCALIZER_USE_CACHE, true))
587: LanguageResourceFinder.clearCache();
588: LanguagePreferences pr = (LanguagePreferences) getSession().getAttribute(LANGUAGE_SESSION_KEY);
589:
590: if (pr == null) {
591: String lang = "";
592: if (isRequestFromPortlet()) {
593: Enumeration enum = null;
594: PortletInfo info = getPortletInfo();
595: if (info.getRenderRequest() != null)
596: enum = getPortletInfo().getRenderRequest().getLocales();
597: else if (info.getActionRequest() != null)
598: enum = getPortletInfo().getActionRequest().getLocales();
599: lang=SalmonPortlet.constructLanguageString(enum);
600: }
601: else
602: lang = getCurrentRequest().getHeader("Accept-Language");
603: if (lang != null) {
604: pr = new LanguagePreferences(lang);
605: getSession().setAttribute(LANGUAGE_SESSION_KEY, pr);
606: }
607: }
608: }
609:
610: /**
611: * This method is called by the framework and should not be called directly
612: */
613: public boolean getForwardPerformed() {
614: return _forwardPerformed;
615: }
616:
617: /**
618: * This method is called by the framework and should not be called directly
619: */
620: public void setForwardPerformed(boolean forwardPerformed) {
621: _forwardPerformed = forwardPerformed;
622: }
623:
624: /**
625: * This method is used to indicate whether components on the page should use the Html disabled attribute for disabled form components
626: */
627: public boolean getUseDisabledAttribute() {
628: return _useDisabledAttribute;
629: }
630:
631: /**
632: * This method is used to indicate whether components on the page should use the Html disabled attribute for disabled form components
633: */
634: public void setUseDisabledAttribute(boolean useDisabledAttribute) {
635: _useDisabledAttribute = useDisabledAttribute;
636: }
637:
638: /**
639: * Sets the Default Skin for all pages. To apply the skin to pages already created you should clear them from the session after making this call.
640: * @param skin the Skin to set
641: * @param forAllApps true if you want to set the skin for all applications on the server, false if only for the app the component is in.
642: */
643: public void setDefaultSkin(Skin skin, boolean forAllApps) {
644: setSkin(skin);
645: String key = "%$DEFAULT_SKIN$%";
646: if (!forAllApps)
647: key = getApplicationName() + key;
648: HttpSession sess = getSession();
649: sess.setAttribute(key, skin);
650: Enumeration e = sess.getAttributeNames();
651: while (e.hasMoreElements()) {
652: String ele = (String) e.nextElement();
653: Object o = sess.getAttribute(ele);
654: if (o instanceof HtmlPageBase && o != this ) {
655: ((HtmlPageBase) o).loadProperties();
656: if (forAllApps
657: || ((HtmlPageBase) o).getApplicationName()
658: .equals(getApplicationName())) {
659: ((HtmlPageBase) o).applySkin(skin, true);
660: }
661: }
662: }
663: }
664:
665: /**
666: * Removes a default skin set by calling the setDefaultSkinMethod
667: * @param forAllApps true if you want to clear the skin for all applications on the server, false if only for the app the component is in.
668: */
669: public void clearDefaultSkin(boolean forAllApps) {
670: String key = "%$DEFAULT_SKIN$%";
671: if (!forAllApps)
672: key = getApplicationName() + key;
673: HttpSession sess = getSession();
674: sess.removeAttribute(key);
675: }
676:
677: /**
678: * Sets the skin for this page and applies it
679: * @param skin
680: */
681: public void setSkin(Skin skin) {
682: _skin = skin;
683: loadProperties();
684: applySkin(skin, true);
685: }
686:
687: /**
688: * Applies the skin to the page. This method is called from the framework and should not be called directly. Instead use setSkin(Skin sk)
689: */
690: public void applySkin(Skin skin, boolean doSetTheme) {
691:
692: }
693:
694: /**
695: * Gets the skin for this page. If one isn't found, the system will look for a default one for the application or all applications on the session.
696: * @return
697: */
698: public Skin getSkin() {
699: HttpSession sess = getSession();
700: Skin ret = _skin;
701: if (ret == null)
702: ret = (Skin) sess.getAttribute(getApplicationName()
703: + "%$DEFAULT_SKIN$%");
704: if (ret == null)
705: ret = (Skin) sess.getAttribute("%$DEFAULT_SKIN$%");
706: return ret;
707: }
708:
709: /**
710: * @returns if the page is launched inside a portlet, this method will provide information on the portlet or null if the page is not launched from a portlet
711: */
712: public PortletInfo getPortletInfo() {
713: return _portletInfo;
714: }
715:
716: /**
717: * @param iframework method, do not call directly
718: */
719: public void setPortletInfo(PortletInfo info) {
720: _portletInfo = info;
721: }
722:
723: /**
724: * @returns true if the page request is from a portlet
725: */
726: public boolean isRequestFromPortlet() {
727: return _portletInfo != null;
728: }
729: }
|