001: /*
002: * Copyright (C) 2006 Methodhead Software LLC. All rights reserved.
003: *
004: * This file is part of TransferCM.
005: *
006: * TransferCM is free software; you can redistribute it and/or modify it under the
007: * terms of the GNU General Public License as published by the Free Software
008: * Foundation; either version 2 of the License, or (at your option) any later
009: * version.
010: *
011: * TransferCM is distributed in the hope that it will be useful, but WITHOUT ANY
012: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
013: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
014: * details.
015: *
016: * You should have received a copy of the GNU General Public License along with
017: * TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
018: * Fifth Floor, Boston, MA 02110-1301 USA
019: */
020:
021: package com.methodhead.shim;
022:
023: import javax.servlet.http.HttpServletRequest;
024: import javax.servlet.http.HttpServletResponse;
025: import java.util.Map;
026: import java.util.List;
027: import java.util.ArrayList;
028: import java.util.Iterator;
029: import java.util.HashMap;
030: import com.methodhead.sitecontext.SiteContext;
031: import org.apache.struts.util.MessageResources;
032: import com.methodhead.tree.Tree;
033: import org.apache.struts.Globals;
034: import org.apache.struts.action.ActionMapping;
035: import org.apache.struts.action.DynaActionForm;
036: import org.apache.struts.util.LabelValueBean;
037: import com.methodhead.tree.FoldingTreeNode;
038: import com.methodhead.auth.AuthUser;
039: import com.methodhead.auth.AuthUtil;
040: import com.methodhead.util.OperationContext;
041: import com.methodhead.util.StrutsUtil;
042: import org.apache.commons.lang.StringUtils;
043: import java.util.regex.Pattern;
044: import java.util.regex.Matcher;
045:
046: /**
047: * A collection of utility methods used in the shim package.
048: */
049: public class ShimUtils {
050:
051: // constructors /////////////////////////////////////////////////////////////
052:
053: // constants ////////////////////////////////////////////////////////////////
054:
055: // classes //////////////////////////////////////////////////////////////////
056:
057: // methods //////////////////////////////////////////////////////////////////
058:
059: /**
060: * Sets the <tt>siteMap</tt> in an application attribute. Site maps are
061: * expensive to load, and therefore stored as application attributes. Since
062: * a single application may run several sites, each with their own site map,
063: * a map of site maps is stored, keyed by site context id.
064: */
065: public static void setSiteMap(HttpServletRequest request,
066: SiteMap siteMap) {
067:
068: SiteContext siteContext = siteMap.getSiteContext();
069:
070: Map siteMapMap = (Map) request.getSession().getServletContext()
071: .getAttribute(ShimGlobals.SITEMAPMAP_KEY);
072:
073: //
074: // set the map if it doesn't already exist
075: //
076: if (siteMapMap == null) {
077: siteMapMap = new HashMap();
078: request.getSession().getServletContext().setAttribute(
079: ShimGlobals.SITEMAPMAP_KEY, siteMapMap);
080: }
081:
082: siteMapMap.put(siteContext.get("id"), siteMap);
083: }
084:
085: /**
086: * Gets the site map for the current site context (as returned by
087: * <tt>SiteContext.getContext()</tt>), loading it if necessary.
088: */
089: public static SiteMap getSiteMap(HttpServletRequest request) {
090:
091: SiteContext siteContext = SiteContext.getContext(request);
092:
093: if (siteContext == null)
094: throw new ShimException("Couldn't get site context.");
095:
096: //
097: // set the map if it doesn't already exist
098: //
099: Map siteMapMap = (Map) request.getSession().getServletContext()
100: .getAttribute(ShimGlobals.SITEMAPMAP_KEY);
101:
102: if (siteMapMap == null) {
103: siteMapMap = new HashMap();
104: request.getSession().getServletContext().setAttribute(
105: ShimGlobals.SITEMAPMAP_KEY, siteMapMap);
106: }
107:
108: //
109: // load and set the siteMap if it doesn't already exist
110: //
111: SiteMap siteMap = (SiteMap) siteMapMap.get(siteContext
112: .get("id"));
113:
114: if (siteMap == null) {
115: siteMap = new SiteMap();
116: siteMap.setSiteContext(siteContext);
117: siteMap.load();
118: siteMapMap.put(siteContext.get("id"), siteMap);
119: }
120:
121: return siteMap;
122: }
123:
124: /**
125: * Gets the site map tree from the session.
126: */
127: public static SiteMapTree getSiteMapTree(HttpServletRequest request) {
128:
129: return (SiteMapTree) request.getSession().getAttribute(
130: ShimGlobals.SITEMAPTREE_KEY);
131: }
132:
133: /**
134: * Returns a menu customized for admin home.
135: */
136: /*
137: public static FoldingTreeNode getHomeMenu(
138: MessageResources resources ) {
139:
140: FoldingTreeNode item = null;
141: FoldingTreeNode subitem = null;
142:
143: //
144: // get the base menu
145: //
146: FoldingTreeNode menu = buildBaseMenu( resources );
147: FoldingTreeNode pageMenu = ( FoldingTreeNode )menu.getChildAt( 2 );
148:
149: //
150: // new
151: //
152: item = new FoldingTreeNode();
153: item.setLabel( resources.getMessage( "shim.menu.fragments" ) );
154: item.setUrl( "htmlFragment.do?action=list" );
155: pageMenu.add( item );
156:
157: item = new FoldingTreeNode();
158: item.setLabel( resources.getMessage( "shim.menu.new" ) );
159: item.setUrl( "newPageForm.do" );
160: pageMenu.add( item );
161:
162: return menu;
163: }
164: */
165:
166: /**
167: * Returns a menu customized for the page being edited in {@link
168: * PageAction#doEditPage doEditPage()}.
169: */
170: /*
171: public static FoldingTreeNode getEditPageMenu(
172: SiteMap siteMap,
173: Page page,
174: MessageResources resources ) {
175:
176: Link link = siteMap.find( page.getInt( "id" ) );
177:
178: FoldingTreeNode item = null;
179: FoldingTreeNode subitem = null;
180:
181: //
182: // get the base menu
183: //
184: FoldingTreeNode menu = buildBaseMenu( resources );
185: FoldingTreeNode pageMenu = ( FoldingTreeNode )menu.getChildAt( 2 );
186:
187: //
188: // new
189: //
190: item = new FoldingTreeNode();
191: item.setLabel( resources.getMessage( "shim.menu.fragments" ) );
192: item.setUrl( "htmlFragment.do?action=list" );
193: pageMenu.add( item );
194:
195: item = new FoldingTreeNode();
196: item.setLabel( resources.getMessage( "shim.menu.new" ) );
197: item.setUrl( "" );
198: pageMenu.add( item );
199:
200: if ( link != siteMap.getRoot() ) {
201: subitem = new FoldingTreeNode();
202: subitem.setLabel( resources.getMessage( "shim.menu.before" ) );
203: subitem.setUrl(
204: "newPageForm.do?destid=" + page.getInt( "id" ) + "&position=before" );
205: item.add( subitem );
206:
207: subitem = new FoldingTreeNode();
208: subitem.setLabel( resources.getMessage( "shim.menu.after" ) );
209: subitem.setUrl(
210: "newPageForm.do?destid=" + page.getInt( "id" ) + "&position=after" );
211: item.add( subitem );
212: }
213:
214: subitem = new FoldingTreeNode();
215: subitem.setLabel( resources.getMessage( "shim.menu.under" ) );
216: subitem.setUrl(
217: "newPageForm.do?destid=" + page.getInt( "id" ) + "&position=under" );
218: item.add( subitem );
219:
220: item = new FoldingTreeNode();
221: item.setLabel( resources.getMessage( "shim.menu.properties" ) );
222: item.setUrl( "configurePageForm.do?id=" + page.get( "id" ) );
223: pageMenu.add( item );
224:
225: if ( link != siteMap.getRoot() ) {
226: item = new FoldingTreeNode();
227: item.setLabel( resources.getMessage( "shim.menu.move" ) );
228: item.setUrl( "movePageForm.do?id=" + page.get( "id" ) );
229: pageMenu.add( item );
230: }
231:
232: item = new FoldingTreeNode();
233: item.setLabel( resources.getMessage( "shim.menu.delete" ) );
234: item.setUrl( "deletePage.do?id=" + page.get( "id" ) );
235: pageMenu.add( item );
236:
237: return menu;
238: }
239: */
240:
241: /**
242: * Returns a list of {@link Module Module}s available to
243: * <tt>siteContext</tt>.
244: */
245: public static List getModules(SiteContext siteContext) {
246:
247: List modules = new ArrayList();
248: modules.add(new TextModule());
249: modules.add(new NavModule());
250: modules.add(new IncludeModule());
251:
252: return modules;
253: }
254:
255: /**
256: * Returns a relative URL for the page associated with
257: * <tt>link</tt>.
258: */
259: public static String getLinkUrl(Link link) {
260:
261: return link.getAlias() + ".shtml";
262: }
263:
264: /**
265: * Returns an relative URL for the page associated with <tt>link</tt>,
266: * specifying a parent directory to get rid of the site context id in page
267: * urls.
268: *
269: * @deprecated Path is no longer necessary with new ShimFilter.
270: */
271: public static String getLinkUrl(Link link, String path) {
272:
273: /*
274: if ( ( path == null ) || "".equals( path ) )
275: return link.getAlias() + ".shtml";
276: else
277: return path + "/" + link.getAlias() + ".shtml";
278: */
279: return link.getAlias() + ".shtml";
280: }
281:
282: /**
283: * NOT UNIT TESTED Instantiates a <tt>ShimPolicy</tt> using <tt>mapping</tt>'s parameter.
284: */
285: public static ShimPolicy getPolicy(ActionMapping mapping) {
286:
287: try {
288: return (ShimPolicy) Class.forName(mapping.getParameter())
289: .newInstance();
290: } catch (Exception e) {
291: throw new ShimException(
292: "Unexpected exception while instantiating \""
293: + mapping.getParameter() + "\":"
294: + e.toString());
295: }
296: }
297:
298: /**
299: * NOT UNIT TESTED Returns a list of <tt>LabelValueBeans</tt> for the existing fragments in
300: * the current site context.
301: */
302: public static List getHtmlFragmentOptions(HttpServletRequest request) {
303:
304: HtmlFragment fragment = new HtmlFragment();
305: fragment.setSiteContext(SiteContext.getContext(request));
306: List list = fragment.loadAll();
307:
308: //
309: // create a list of options
310: //
311: List options = new ArrayList();
312: for (Iterator iter = list.iterator(); iter.hasNext();) {
313: HtmlFragment f = (HtmlFragment) iter.next();
314: options.add(new LabelValueBean(f.getString("name"), ""
315: + f.getInt("id")));
316: }
317:
318: return options;
319: }
320:
321: /**
322: * NOT UNIT TESTED Sets up a <tt>SiteContext</tt> and <tt>SiteMapTree</tt>
323: * appropriately for shim session.
324: */
325: public static void setUpShimSession(HttpServletRequest request,
326: SiteContext context) {
327:
328: SiteContext.setContext(request, context);
329:
330: //
331: // override any site context that ShimFilter might have set in the request
332: //
333: request.setAttribute(SiteContext.SITECONTEXT_KEY, context);
334:
335: SiteMapTree tree = new SiteMapTree();
336: tree.build(ShimUtils.getSiteMap(request));
337: request.getSession().setAttribute(ShimGlobals.SITEMAPTREE_KEY,
338: tree);
339: }
340:
341: /**
342: * NOT UNIT TESTED Cleans up all shim-related session attributes
343: */
344: public static void tearDownShimSession(HttpServletRequest request) {
345:
346: request.getSession().removeAttribute(
347: SiteContext.SITECONTEXT_KEY);
348: request.getSession().removeAttribute(ShimGlobals.MODE_KEY);
349: request.getSession().removeAttribute(
350: ShimGlobals.SITEMAPTREE_KEY);
351: }
352:
353: /**
354: * NOT UNIT TESTED Sets up the menu for the current request by assembling an
355: * <tt>OperationContext</tt> and <tt>ShimPolicy</tt> and invoking the
356: * policy's <tt>setUpMenu()</tt> method.
357: */
358: public static void setUpMenu(HttpServletRequest request,
359: HttpServletResponse response) {
360:
361: ActionMapping mapping = (ActionMapping) request
362: .getAttribute(Globals.MAPPING_KEY);
363:
364: DynaActionForm form = (DynaActionForm) request
365: .getAttribute(mapping.getName());
366:
367: AuthUser user = AuthUtil.getUser(request);
368:
369: OperationContext op = new OperationContext(mapping, form,
370: request, response, user);
371:
372: ShimPolicy policy = (ShimPolicy) StrutsUtil.getPolicy(mapping);
373:
374: policy.setUpMenu(op);
375: }
376:
377: /**
378: * Returns <code>true</code> if there is a SiteContext in the session.
379: */
380: public static boolean displayEditElements(HttpServletRequest request) {
381: return request.getSession().getAttribute(
382: SiteContext.SITECONTEXT_KEY) != null;
383: }
384:
385: /**
386: * Converts a file name to a label by splitting words in the file name on
387: * capital letters and removing any file extension. The first letter of the
388: * label is always capitalized. The extension is assumed to be anything
389: * after the first period in the name. Returns "<null>" if
390: * <code>fileName</code> is null.
391: */
392: public static String fileNameToLabel(String fileName) {
393:
394: if (null == fileName) {
395: return "<null>";
396: }
397:
398: if (StringUtils.isBlank(fileName)) {
399: return "";
400: }
401:
402: //
403: // remove extension
404: //
405: fileName = StringUtils.substringBefore(fileName, ".");
406:
407: //
408: // capitalize first letter
409: //
410: fileName = StringUtils.capitalize(fileName);
411:
412: //
413: // split on caps
414: //
415: Pattern pattern = Pattern.compile("([A-Z][^A-Z]*)");
416: Matcher matcher = pattern.matcher(fileName);
417:
418: StringBuffer buf = new StringBuffer();
419:
420: while (matcher.find()) {
421: buf.append(StringUtils.strip(matcher.group(1)));
422: buf.append(" ");
423: }
424:
425: return StringUtils.strip(buf.toString());
426: }
427:
428: // properties ///////////////////////////////////////////////////////////////
429:
430: // attributes ///////////////////////////////////////////////////////////////
431: }
|