KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > methodhead > shim > NavModule


1 /*
2  * Copyright (C) 2006 Methodhead Software LLC. All rights reserved.
3  *
4  * This file is part of TransferCM.
5  *
6  * TransferCM is free software; you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation; either version 2 of the License, or (at your option) any later
9  * version.
10  *
11  * TransferCM is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
18  * Fifth Floor, Boston, MA 02110-1301 USA
19  */

20
21 package com.methodhead.shim;
22
23 import java.util.HashMap JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.io.IOException JavaDoc;
27
28 import com.methodhead.persistable.Persistable;
29 import com.methodhead.persistable.PersistableException;
30
31 import org.apache.commons.beanutils.DynaClass;
32 import org.apache.commons.beanutils.DynaProperty;
33 import org.apache.commons.beanutils.BasicDynaClass;
34 import javax.servlet.http.HttpServletRequest JavaDoc;
35 import javax.servlet.http.HttpServletResponse JavaDoc;
36 import javax.servlet.jsp.JspWriter JavaDoc;
37 import org.apache.struts.action.ActionMapping;
38 import org.apache.struts.action.DynaActionForm;
39 import org.apache.struts.action.ActionForward;
40 import javax.servlet.RequestDispatcher JavaDoc;
41 import javax.servlet.ServletException JavaDoc;
42 import com.methodhead.sitecontext.SiteContext;
43 import org.apache.commons.lang.StringUtils;
44 import org.apache.commons.lang.exception.ExceptionUtils;
45
46 /**
47  * A NavModule. The following fields are defined:
48  * <ul>
49  * <li><tt>int sitecontext_id = 0</tt></li>
50  * <li><tt>String template = ""</tt></li>
51  * <li><tt>String panel = ""</tt></li>
52  * <li><tt>Boolean hideroot = false</tt></li>
53  * <li><tt>String type = ""</tt></li>
54  * <li><tt>String separator = ""</tt></li>
55  * <li><tt>String jsp = ""</tt></li>
56  * <li><tt>Integer startlev = 1</tt></li>
57  * <li><tt>Integer contextlev = 1</tt></li>
58  * <li><tt>Integer depthlev = 1</tt></li>
59  * <li><tt>Integer toplev = 1</tt></li>
60  * <li><tt>String header = ""</tt></li>
61  * <li><tt>String link = ""</tt></li>
62  * <li><tt>String curlink = ""</tt></li>
63  * <li><tt>String footer = ""</tt></li>
64  * </ul>
65  */

66 public class NavModule
67 extends
68   Persistable
69 implements
70   Module {
71
72   protected static DynaClass dynaClass_ = null;
73
74   static {
75     DynaProperty[] dynaProperties =
76       new DynaProperty[] {
77         new DynaProperty( "sitecontext_id", Integer JavaDoc.class ),
78         new DynaProperty( "template", String JavaDoc.class ),
79         new DynaProperty( "panel", String JavaDoc.class ),
80         new DynaProperty( "hideroot", Boolean JavaDoc.class ),
81         new DynaProperty( "type", String JavaDoc.class ),
82         new DynaProperty( "separator", String JavaDoc.class ),
83         new DynaProperty( "jsp", String JavaDoc.class ),
84         new DynaProperty( "startlev", Integer JavaDoc.class ),
85         new DynaProperty( "contextlev", Integer JavaDoc.class ),
86         new DynaProperty( "depthlev", Integer JavaDoc.class ),
87         new DynaProperty( "toplev", Integer JavaDoc.class ),
88         new DynaProperty( "header", String JavaDoc.class ),
89         new DynaProperty( "link", String JavaDoc.class ),
90         new DynaProperty( "curlink", String JavaDoc.class ),
91         new DynaProperty( "footer", String JavaDoc.class )
92       };
93
94     dynaClass_ =
95       new BasicDynaClass(
96         "shim_nav", NavModule.class, dynaProperties );
97   }
98
99   // constructors /////////////////////////////////////////////////////////////
100

101   public NavModule() {
102     super( dynaClass_ );
103     init();
104   }
105
106   public NavModule(
107     DynaClass dynaClass ) {
108     super( dynaClass );
109     init();
110   }
111
112   // constants ////////////////////////////////////////////////////////////////
113

114   public static final String JavaDoc TYPE_TEXTSEPARATED = "TEXTSEPARATED";
115   public static final String JavaDoc TYPE_JSP = "JSP";
116   public static final String JavaDoc TYPE_FOLDING = "FOLDING";
117
118   public static final String JavaDoc DEFAULT_TYPE = TYPE_TEXTSEPARATED;
119   public static final String JavaDoc DEFAULT_SEPARATOR = "&nbsp;|&nbsp;";
120
121   // classes //////////////////////////////////////////////////////////////////
122

123   // methods //////////////////////////////////////////////////////////////////
124

125   private void init() {
126     setInt( "sitecontext_id", 0 );
127     setString( "template", "" );
128     setString( "panel", "" );
129     setBoolean( "hideroot", false );
130     setString( "type", "" );
131     setString( "separator", "" );
132     setString( "jsp", "" );
133     setInt( "startlev", 1 );
134     setInt( "contextlev", 1 );
135     setInt( "depthlev", 1 );
136     setInt( "toplev", 1 );
137     setString( "header", "" );
138     setString( "link", "" );
139     setString( "curlink", "" );
140     setString( "footer", "" );
141   }
142
143   /**
144    * Loads the nav for the site context, template, and panel set up when init
145    * is called.
146    */

147   public void load() {
148     load(
149       "sitecontext_id=" + getInt( "sitecontext_id" ) +
150       " AND template=" + getSqlLiteral( getString( "template" ) ) +
151       " AND panel=" + getSqlLiteral( getString( "panel" ) ) );
152   }
153
154   /**
155    * Saves the nav for the site context, template, and panel set up when init
156    * is called; be sure the module is created first.
157    */

158   public void save() {
159     save(
160       "sitecontext_id=" + getInt( "sitecontext_id" ) +
161       " AND template=" + getSqlLiteral( getString( "template" ) ) +
162       " AND panel=" + getSqlLiteral( getString( "panel" ) ) );
163   }
164
165   public String JavaDoc getName() {
166     return "Navigation";
167   }
168
169   public void init(
170     Page page,
171     String JavaDoc panel ) {
172
173     setInt( "sitecontext_id", page.getSiteContext().getInt( "id" ) );
174     setString( "template", page.getString( "template" ) );
175     setString( "panel", panel );
176
177     //
178
// we'll need this for getLinkUrl()
179
//
180
siteContextPath_ = page.getSiteContext().getString( "path" );
181   }
182
183   public void create() {
184     //
185
// does the nav already exist?
186
//
187
try {
188       load();
189     }
190     catch ( PersistableException e ) {
191       //
192
// create the nav
193
//
194
setString( "type", DEFAULT_TYPE );
195       setString( "separator", DEFAULT_SEPARATOR );
196       saveNew();
197     }
198   }
199
200   public void destroy() {
201     //
202
// do nothing; we actually just let nav's pile up for now
203
//
204
}
205
206   /**
207    * Renders a link in a text-separated nav. <tt>link</tt> and
208    * <tt>curlink</tt> are used if they are set, otherwise a plain hyperlink is
209    * renedered.
210    */

211   protected void renderTextSeparatedLink(
212     JspWriter JavaDoc out,
213     Link link,
214     Link cur,
215     boolean isEditMode )
216   throws IOException JavaDoc {
217
218     String JavaDoc s = null;
219
220     if ( link.isRoot() ) {
221       if ( cur == link )
222         s = getString( "curlink" );
223       else
224         s = getString( "link" );
225     }
226     else {
227       if ( cur.isNodeAncestor( link ) )
228         s = getString( "curlink" );
229       else
230         s = getString( "link" );
231     }
232
233     String JavaDoc url = ShimUtils.getLinkUrl( link );
234
235     if ( "".equals( s ) ) {
236       out.print( "<a HREF=\"" + url + "\">" + link.getTitle() + "</a>" );
237     }
238     else {
239       s = StringUtils.replace(
240         s, FoldingNavRenderer.URL_KEY, url );
241       s = StringUtils.replace(
242         s, FoldingNavRenderer.TITLE_KEY, link.getTitle() );
243     }
244
245     out.print( s );
246   }
247
248   public void display(
249     HttpServletRequest JavaDoc request,
250     HttpServletResponse JavaDoc response,
251     JspWriter JavaDoc out )
252   throws
253     IOException JavaDoc {
254
255     //
256
// load the nav
257
//
258
load();
259
260     //
261
// get things we'll need
262
//
263
Page curPage = ( Page )request.getAttribute( ShimGlobals.PAGE_KEY );
264     SiteMap siteMap = ShimUtils.getSiteMap( request );
265     Link root = ( Link )siteMap.getRoot();
266     Link cur = siteMap.find( curPage.getInt( "id" ) );
267     boolean isEditMode =
268       ShimGlobals.MODE_EDIT.equals(
269         request.getSession().getAttribute( ShimGlobals.MODE_KEY ) );
270
271     //
272
// text separated
273
//
274
if ( TYPE_TEXTSEPARATED.equals( getString( "type" ) ) ) {
275       try {
276         if ( root != null ) {
277
278           out.print( getString( "header" ) );
279
280           //
281
// remember when we display a link, that way we'll know we have to
282
// display a separator
283
//
284
boolean linkRendered = false;
285
286           //
287
// render root link
288
//
289
if ( !getBoolean( "hideroot" ) && !root.getHidden() ) {
290             renderTextSeparatedLink( out, root, cur, isEditMode );
291             linkRendered = true;
292           }
293
294           //
295
// render the top-level links
296
//
297
for ( int i = 0; i < root.getChildCount(); i++ ) {
298             Link link = ( Link )root.getChildAt( i );
299
300             if ( !link.getHidden() ) {
301
302               if ( linkRendered ) {
303                 out.print( getString( "separator" ) );
304               }
305
306               renderTextSeparatedLink( out, link, cur, isEditMode );
307               linkRendered = true;
308             }
309           }
310
311           out.print( getString( "footer" ) );
312         }
313       }
314       catch ( IOException JavaDoc e ) {
315         throw new ShimException( "Unexpected IOException while printing nav." );
316       }
317     }
318
319     //
320
// jsp
321
//
322
else if ( TYPE_JSP.equals( getString( "type" ) ) ) {
323       try {
324         //
325
// put the current link into the request
326
//
327
request.setAttribute( ShimGlobals.CURRENTLINK_KEY, cur );
328
329         //
330
// include the jsp
331
//
332
SiteContext siteContext = SiteContext.getContext( request );
333
334         out.flush();
335
336         RequestDispatcher JavaDoc dispatcher =
337           request.getSession().getServletContext().getRequestDispatcher(
338             "/WEB-INF/resources/" + siteContext.getInt( "id" ) + "/" +
339             getString( "jsp" ) );
340
341         dispatcher.include( request, response );
342       }
343       catch ( ServletException JavaDoc e ) {
344         out.println( ExceptionUtils.getStackTrace( e ) );
345       }
346     }
347
348     //
349
// folding
350
//
351
else if ( TYPE_FOLDING.equals( getString( "type" ) ) ) {
352       try {
353         FoldingNavRenderer renderer = new FoldingNavRenderer();
354         renderer.setRoot( root );
355         renderer.setCur( cur );
356         renderer.setStart( getInt( "startlev" ) );
357         renderer.setContext( getInt( "contextlev" ) );
358         renderer.setDepth( getInt( "depthlev" ) );
359         renderer.setTop( getInt( "toplev" ) );
360         renderer.setHeader( getString( "header" ) );
361         renderer.setLink( getString( "link" ) );
362         renderer.setCurLink( getString( "curlink" ) );
363         renderer.setFooter( getString( "footer" ) );
364         renderer.setIsEditMode(
365           ShimGlobals.MODE_EDIT.equals(
366             request.getSession().getAttribute( ShimGlobals.MODE_KEY ) ) );
367
368         out.println( renderer.getNavHtml() );
369       }
370       catch ( IOException JavaDoc e ) {
371         throw new ShimException( "Unexpected IOException while printing nav." );
372       }
373     }
374     else {
375       throw new ShimException(
376         "Unexpected nav type \"" + getString( "type" ) + "\"." );
377     }
378   }
379
380   public boolean isConfigurable() {
381     return true;
382   }
383
384   public ActionForward configure(
385     ActionMapping mapping,
386     DynaActionForm form,
387     HttpServletRequest JavaDoc request,
388     HttpServletResponse JavaDoc response ) {
389
390     return new ActionForward(
391       "/configureNavModuleForm.do?pageid=" + form.get( "pageid" ) +
392       "&panel=" + form.get( "panel" ) );
393   }
394
395   public boolean isEditable() {
396     return false;
397   }
398
399   /**
400    * Not implemented.
401    */

402   public void update(
403     String JavaDoc text ) {
404   }
405
406   public void copyTo(
407     Page page ) {
408     //
409
// nav modules don't store page-specific data (only
410
// template/sitecontext-specific), so since this nav module already exists,
411
// we don't have to do anything
412
//
413
}
414
415   // properties ///////////////////////////////////////////////////////////////
416

417   // attributes ///////////////////////////////////////////////////////////////
418

419   private String JavaDoc siteContextPath_ = null;
420 }
421
Popular Tags