001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/portal/tags/sakai_2-4-1/portal-render-engine-impl/impl/src/test/org/sakaiproject/portal/charon/test/MockCharonPortal.java $
003: * $Id: MockCharonPortal.java 21708 2007-02-18 21:59:28Z ian@caret.cam.ac.uk $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.portal.charon.test;
021:
022: import java.io.FileInputStream;
023: import java.io.FileOutputStream;
024: import java.io.FileWriter;
025: import java.io.IOException;
026: import java.util.ArrayList;
027: import java.util.HashMap;
028: import java.util.List;
029: import java.util.Map;
030:
031: import javax.servlet.http.HttpServlet;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035: import org.sakaiproject.portal.api.PortalRenderContext;
036: import org.sakaiproject.portal.api.PortalRenderEngine;
037: import org.sakaiproject.portal.charon.velocity.VelocityPortalRenderEngine;
038: import org.sakaiproject.util.ResourceLoader;
039: import org.w3c.tidy.Tidy;
040:
041: /**
042: * <p>
043: * This class operates as Mock portal to enable testing of a set of templates.
044: * It can be used to drive any render engine, but is setup for the default
045: * render engine. It is run as a unit test.
046: * </p>
047: */
048: public class MockCharonPortal extends HttpServlet {
049:
050: private static ResourceLoader rloader = new ResourceLoader(
051: "sitenav");
052:
053: /** Our log (commons). */
054: private static Log log = LogFactory.getLog(MockCharonPortal.class);
055:
056: private PortalRenderEngine rengine;
057:
058: public MockCharonPortal() throws Exception {
059: String renderEngineClass = VelocityPortalRenderEngine.class
060: .getName();
061:
062: Class c = Class.forName(renderEngineClass);
063: rengine = (PortalRenderEngine) c.newInstance();
064: rengine.init();
065:
066: }
067:
068: public void doError() throws IOException {
069:
070: // start the response
071: PortalRenderContext rcontext = startPageContext();
072:
073: showSession(rcontext);
074:
075: showSnoop(rcontext);
076:
077: sendResponse(rcontext, "error");
078: }
079:
080: private void showSnoop(PortalRenderContext rcontext) {
081:
082: rcontext.put("snoopRequest", "snoopRequest");
083:
084: Map m = new HashMap();
085: m.put("param1", "configparam1");
086: m.put("param1", "configparam1");
087: rcontext.put("snoopServletConfigParams", m);
088: rcontext.put("snoopRequest", "snoopRequest");
089: rcontext.put("snoopRequestHeaders", m);
090: rcontext.put("snoopRequestParamsSingle", m);
091: rcontext.put("snoopRequestParamsMulti", m);
092: rcontext.put("snoopRequestAttr", m);
093: }
094:
095: public void doGallery() throws IOException {
096: PortalRenderContext rcontext = startPageContext();
097:
098: // the 'little' top area
099: includeGalleryNav(rcontext);
100:
101: includeWorksite(rcontext);
102:
103: includeBottom(rcontext);
104:
105: sendResponse(rcontext, "gallery");
106: }
107:
108: public void doGalleryTabs() throws IOException {
109:
110: PortalRenderContext rcontext = startPageContext();
111:
112: // Remove the logout button from gallery since it is designed to be
113: // included within
114: // some other application (like a portal) which will want to control
115: // logout.
116:
117: // includeTabs(out, req, session, siteId, "gallery", true);
118: includeTabs(rcontext);
119:
120: sendResponse(rcontext, "gallery-tabs");
121: }
122:
123: public void doNavLogin() throws IOException {
124: // start the response
125: PortalRenderContext rcontext = startPageContext();
126:
127: includeLogo(rcontext);
128:
129: sendResponse(rcontext, "login");
130: }
131:
132: public void doNavLoginGallery() throws IOException {
133: // start the response
134:
135: PortalRenderContext rcontext = startPageContext();
136:
137: includeGalleryLogin(rcontext);
138: // end the response
139: sendResponse(rcontext, "gallery-login");
140: }
141:
142: public void doPage() throws IOException {
143: PortalRenderContext rcontext = startPageContext();
144:
145: includePage(rcontext);
146:
147: sendResponse(rcontext, "page");
148: }
149:
150: private PortalRenderContext startPageContext() {
151: PortalRenderContext rcontext = rengine.newRenderContext(null);
152: rcontext.put("pageSkinRepo", "skinRepo");
153: rcontext.put("pageSkin", "skin");
154: rcontext.put("pageTitle", "Web.escapeHtml(title)");
155: rcontext.put("pageScriptPath", "getScriptPath()");
156: rcontext.put("pageTop", Boolean.valueOf(true));
157: rcontext.put("pageSiteType", "class=\"siteType\" ");
158: rcontext.put("toolParamResetState", "PARM_STATE_RESET");
159: rcontext.put("rloader", rloader);
160:
161: return rcontext;
162: }
163:
164: public void doSite() throws IOException {
165: PortalRenderContext rcontext = startPageContext();
166:
167: // the 'full' top area
168: includeSiteNav(rcontext);
169:
170: includeWorksite(rcontext);
171:
172: includeBottom(rcontext);
173:
174: // end the response
175: sendResponse(rcontext, "site");
176: }
177:
178: public void doSiteTabs() throws IOException {
179: // start the response
180: PortalRenderContext rcontext = startPageContext();
181:
182: includeLogo(rcontext);
183: includeTabs(rcontext);
184:
185: sendResponse(rcontext, "site-tabs");
186: }
187:
188: public void doWorksite() throws IOException {
189:
190: PortalRenderContext rcontext = startPageContext();
191:
192: includeWorksite(rcontext);
193:
194: // end the response
195: sendResponse(rcontext, "worksite");
196: }
197:
198: protected void includeBottom(PortalRenderContext rcontext) {
199:
200: {
201: List l = new ArrayList();
202: l.add("bottomnav1");
203: l.add("bottomnav2");
204: rcontext.put("bottomNav", l);
205: }
206:
207: rcontext.put("bottomNavSitNewWindow", "site_newwindow");
208: {
209:
210: List l = new ArrayList();
211: Map m = new HashMap();
212: m.put("poweredByUrl", "poweredByUrl[i]");
213: m.put("poweredByImage", "poweredByImage[i]");
214: m.put("poweredByAltText", "poweredByAltText[i]");
215: l.add(m);
216: rcontext.put("bottomNavPoweredBy", l);
217:
218: }
219: {
220: List l = new ArrayList();
221: Map m = new HashMap();
222: m.put("poweredByUrl", "http://sakaiproject.org");
223: m.put("poweredByImage", "/library/image/sakai_powered.gif");
224: m.put("poweredByAltText", "Powered by Sakai");
225: l.add(m);
226: rcontext.put("bottomNavPoweredBy", l);
227: }
228:
229: rcontext.put("bottomNavService", "service");
230: rcontext.put("bottomNavCopyright", "copyright");
231: rcontext.put("bottomNavServiceVersion", "serviceVersion");
232: rcontext.put("bottomNavSakaiVersion", "sakaiVersion");
233: rcontext.put("bottomNavServer", "server");
234: }
235:
236: protected void includeGalleryLogin(PortalRenderContext rcontext)
237: throws IOException {
238: includeLogin(rcontext);
239: }
240:
241: protected void includeGalleryNav(PortalRenderContext rcontext)
242: throws IOException {
243: rcontext.put("galleryHasAccessibilityURL", Boolean
244: .valueOf(true));
245:
246: rcontext.put("galleryAccessibilityURL", "accessibilityURL");
247: // rcontext.put("gallarySitAccessibility", "sit_accessibility");
248: // rcontext.put("gallarySitJumpcontent", "sit_jumpcontent");
249: // rcontext.put("gallarySitJumptools", "sit_jumptools");
250: // rcontext.put("gallarySitJumpworksite", "sit_jumpworksite");
251: rcontext.put("gallaryLoggedIn", Boolean.valueOf(true));
252: includeTabs(rcontext);
253:
254: }
255:
256: protected void includeLogo(PortalRenderContext rcontext)
257: throws IOException {
258: rcontext.put("logoSkin", "skin");
259: rcontext.put("logoSkinRepo", "skinRepo");
260: rcontext.put("logoSiteType", "siteType");
261: rcontext.put("logoSiteClass", "cssClass");
262: includeLogin(rcontext);
263: }
264:
265: protected void includeLogin(PortalRenderContext rcontext) {
266:
267: rcontext.put("loginTopLogin", Boolean.valueOf(true));
268: rcontext.put("loginLogInOutUrl", "logInOutUrl");
269: rcontext.put("loginMessage", "message");
270: rcontext.put("loginImage1", "image1");
271: rcontext.put("image1HasImage1", Boolean.valueOf(true));
272: rcontext.put("loginLogInOutUrl2", "logInOutUrl2");
273: rcontext.put("loginHasLogInOutUrl2", Boolean.valueOf(true));
274: rcontext.put("loginMessage2", "message2");
275: rcontext.put("loginImage2", "image2");
276: rcontext.put("image1HasImage2", Boolean.valueOf(true));
277:
278: rcontext.put("loginPortalPath", "portalPath");
279: rcontext.put("loginEidWording", "eidWording");
280: rcontext.put("loginPwWording", "pwWording");
281: rcontext.put("loginWording", "loginWording");
282: }
283:
284: protected void includePage(PortalRenderContext rcontext)
285: throws IOException {
286: // divs to wrap the tools
287: rcontext.put("pageWrapperClass", "wrapperClass");
288: rcontext.put("pageColumnLayout", "col1of2");
289: {
290: List toolList = new ArrayList();
291: toolList.add(includeTool());
292: toolList.add(includeTool());
293: rcontext.put("pageColumn0Tools", toolList);
294: }
295:
296: rcontext.put("pageTwoColumn", Boolean.valueOf(true));
297: {
298: List toolList = new ArrayList();
299: toolList.add(includeTool());
300: rcontext.put("pageColumn1Tools", toolList);
301: }
302: }
303:
304: protected void includePageNav(PortalRenderContext rcontext)
305: throws IOException {
306: rcontext.put("pageNavPublished", Boolean.valueOf(true));
307: rcontext.put("pageNavType", "type");
308: rcontext.put("pageNavIconUrl", "iconUrl");
309: // rcontext.put("pageNavSitToolsHead", "sit_toolshead");
310:
311: List l = new ArrayList();
312: Map m = new HashMap();
313: m.put("current", Boolean.valueOf(true));
314: m.put("ispopup", Boolean.valueOf(false));
315: m.put("pagePopupUrl", "pagePopupUrl");
316: m.put("pageIdWeb", "pageId");
317: m.put("jsPageTitle", "pageTitleJS");
318: m.put("htmlPageTitle", "pageTitleHTML");
319: m.put("pagerefUrl", "pagerefUrl");
320: l.add(m);
321: m.put("current", Boolean.valueOf(false));
322: m.put("ispopup", Boolean.valueOf(false));
323: m.put("pagePopupUrl", "pagePopupUrl");
324: m.put("pageIdWeb", "pageId");
325: m.put("jsPageTitle", "pageTitleJS");
326: m.put("htmlPageTitle", "pageTitleHTML");
327: m.put("pagerefUrl", "pagerefUrl");
328: l.add(m);
329: rcontext.put("pageNavTools", l);
330:
331: rcontext.put("pageNavShowHelp", Boolean.valueOf(true));
332: rcontext.put("pageNavHelpUrl", "helpUrl");
333: // rcontext.put("pageNavSitHelp", "sit_help");
334:
335: // rcontext.put("pageNavSitPresenceTitle", "sit_presencetitle");
336: // rcontext.put("pageNavSitPresenceFrameTitle",
337: // "sit_presenceiframetit");
338: rcontext.put("pageNavShowPresenceLoggedIn", Boolean
339: .valueOf(true));
340: rcontext.put("pageNavPresenceUrl", "presenceUrl");
341: // rcontext.put("pageNavSitContentshead", "sit_contentshead");
342:
343: }
344:
345: protected void includeSiteNav(PortalRenderContext rcontext)
346: throws IOException {
347: rcontext.put("siteNavHasAccessibilityURL", Boolean
348: .valueOf((true)));
349: rcontext.put("siteNavAccessibilityURL", "accessibilityURL");
350: // rcontext.put("siteNavSitAccessability", "sit_accessibility");
351: // rcontext.put("siteNavSitJumpContent", "sit_jumpcontent");
352: // rcontext.put("siteNavSitJumpTools", "sit_jumptools");
353: // rcontext.put("siteNavSitJumpWorksite", "sit_jumpworksite");
354:
355: rcontext.put("siteNavLoggedIn", Boolean.valueOf(true));
356:
357: includeLogo(rcontext);
358: includeTabs(rcontext);
359: }
360:
361: protected void includeTabs(PortalRenderContext rcontext)
362: throws IOException {
363:
364: rcontext.put("tabsCssClass", "cssClass");
365: // rcontext.put("tabsSitWorksiteHead", "sit_worksiteshead");
366: rcontext.put("tabsCurMyWorkspace", Boolean.valueOf(true));
367: // rcontext.put("tabsSitMyWorkspace", "sit_mywor");
368: rcontext.put("tabsSiteUrl", "mySiteUrl");
369: // rcontext.put("tabsSitWorksite", "sit_worksite");
370:
371: List l = new ArrayList();
372: {
373: Map m = new HashMap();
374: m.put("isCurrentSite", Boolean.valueOf(false));
375: m.put("siteTitle", "siteTitle");
376: m.put("siteUrl", "Web.escapeHtml(s.getTitle())");
377: l.add(m);
378: l.add(m);
379:
380: }
381: rcontext.put("tabsSites", l);
382:
383: rcontext.put("tabsHasExtraTitle", Boolean.valueOf(true));
384:
385: rcontext.put("tabsExtraTitle", "Web.escapeHtml(extraTitle)");
386: rcontext.put("tabsMoreSitesShow", Boolean.valueOf(true));
387: // rcontext.put("tabsSitSelectMessage", "sit_selectmessage");
388: // rcontext.put("tabsSitMode", "sit_more");
389: {
390: Map m = new HashMap();
391:
392: m.put("siteTitle", "Web.escapeHtml(s.getTitle())");
393: m.put("siteUrl", "siteUrl");
394: l.add(m);
395: l.add(m);
396: }
397: rcontext.put("tabsMoreSites", l);
398:
399: rcontext.put("tabsAddLogout", Boolean.valueOf(true));
400: rcontext.put("tabsLogoutUrl", "logoutUrl");
401: // rcontext.put("tabsSitLog", "sit_log");
402: }
403:
404: protected Map includeTool() throws IOException {
405: Map toolMap = new HashMap();
406: toolMap.put("toolUrl", "toolUrl");
407: toolMap.put("toolPlacementIDJS", "Main_"
408: + System.currentTimeMillis());
409: toolMap.put("toolTitle", "titleString");
410: toolMap.put("toolShowResetButton", Boolean.valueOf(true));
411: toolMap.put("toolShowHelpButton", Boolean.valueOf(true));
412: toolMap.put("toolHelpActionUrl", "helpActionUrl");
413: return toolMap;
414: }
415:
416: protected void includeWorksite(PortalRenderContext rcontext)
417: throws IOException {
418: // add the page navigation with presence
419: includePageNav(rcontext);
420:
421: // add the page
422: includePage(rcontext);
423: }
424:
425: /**
426: * Output some session information
427: *
428: * @param rcontext
429: * The print writer
430: * @param html
431: * If true, output in HTML, else in text.
432: */
433: protected void showSession(PortalRenderContext rcontext) {
434: rcontext.put("sessionSession", "s");
435: rcontext.put("sessionToolSession", "ts");
436: }
437:
438: protected void sendResponse(PortalRenderContext rcontext,
439: String template) throws IOException {
440: // get the writer
441: FileWriter f = new FileWriter(template + ".html");
442:
443: log.info("Context Dump is " + rcontext.dump());
444:
445: try {
446: log.info("Rendering " + rcontext + " to " + template);
447: rengine.render(template, rcontext, f);
448: } catch (Exception e) {
449: throw new RuntimeException("Failed to render template ", e);
450: }
451: f.close();
452:
453: Tidy t = new Tidy();
454: FileOutputStream fo = new FileOutputStream(template
455: + ".html.tidy.txt");
456: t.setIndentContent(true);
457: t.setXHTML(true);
458: t.parse(new FileInputStream(template + ".html"), fo);
459:
460: }
461:
462: }
|