001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018:
019: package org.apache.roller.ui.core;
020:
021: import java.text.ParsePosition;
022: import java.text.SimpleDateFormat;
023: import java.util.Calendar;
024: import java.util.Date;
025:
026: import javax.servlet.ServletContext;
027: import javax.servlet.ServletRequest;
028: import javax.servlet.http.HttpServletRequest;
029: import javax.servlet.jsp.PageContext;
030:
031: import org.apache.commons.lang.StringUtils;
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034: import org.apache.roller.RollerException;
035: import org.apache.roller.config.RollerRuntimeConfig;
036: import org.apache.roller.business.Roller;
037: import org.apache.roller.business.RollerFactory;
038: import org.apache.roller.pojos.Template;
039: import org.apache.roller.business.UserManager;
040: import org.apache.roller.business.WeblogManager;
041: import org.apache.roller.pojos.BookmarkData;
042: import org.apache.roller.pojos.FolderData;
043: import org.apache.roller.pojos.UserData;
044: import org.apache.roller.pojos.WeblogCategoryData;
045: import org.apache.roller.pojos.WeblogEntryData;
046: import org.apache.roller.pojos.WebsiteData;
047: import org.apache.roller.util.DateUtil;
048: import org.apache.roller.util.Utilities;
049:
050: //////////////////////////////////////////////////////////////////////////////
051: /**
052: * Access to objects and values specified by request. Parses out arguments from
053: * request URL needed for various parts of Roller and makes them available via
054: * getter methods.
055: * <br/><br/>
056: *
057: * These forms of pathinfo get special support (where 'handle' indicates website):
058: * <br/><br/>
059: *
060: * <pre>
061: * [handle] - get default page for user for today's date
062: * [handle]/[date] - get default page for user for specified date
063: * [handle]/[pagelink] - get specified page for today's date
064: * [handle]/[pagelink]/[date] - get specified page for specified date
065: * [handle]/[pagelink]/[anchor] - get specified page & entry (by anchor)
066: * [handle]/[pagelink]/[date]/[anchor] - get specified page & entry (by anchor)
067: * </pre>
068: *
069: * @author David M Johnson
070: */
071: public class RollerRequest {
072: //----------------------------------------------------------------- Fields
073:
074: private static Log mLogger = LogFactory.getFactory().getInstance(
075: RollerRequest.class);
076:
077: private BookmarkData mBookmark;
078: private ServletContext mContext = null;
079: private Date mDate = null;
080: private String mDateString = null;
081: private String mPathInfo = null;
082: private String mPageLink = null;
083: private Template mPage;
084: private PageContext mPageContext = null;
085: private HttpServletRequest mRequest = null;
086: private WebsiteData mWebsite;
087: private WeblogEntryData mWeblogEntry;
088: private WeblogCategoryData mWeblogCategory;
089:
090: private boolean mIsDaySpecified = false;
091: private boolean mIsMonthSpecified = false;
092:
093: private static ThreadLocal mRollerRequestTLS = new ThreadLocal();
094:
095: public static final String ROLLER_REQUEST = "roller_request";
096:
097: private SimpleDateFormat m8charDateFormat = DateUtil
098: .get8charDateFormat();
099: private SimpleDateFormat m6charDateFormat = DateUtil
100: .get6charDateFormat();
101:
102: //----------------------------------------------------------- Constructors
103:
104: /** Construct Roller request for a Servlet request */
105: public RollerRequest(HttpServletRequest req, ServletContext ctx)
106: throws RollerException {
107: mRequest = req;
108: mContext = ctx;
109: init();
110: }
111:
112: /** Convenience */
113: public RollerRequest(ServletRequest req, ServletContext ctx)
114: throws RollerException {
115: mRequest = (HttpServletRequest) req;
116: mContext = ctx;
117: init();
118: }
119:
120: public RollerRequest(PageContext pCtx) throws RollerException {
121: mRequest = (HttpServletRequest) pCtx.getRequest();
122: mContext = pCtx.getServletContext();
123: mPageContext = pCtx;
124: init();
125: }
126:
127: private void init() throws RollerException {
128: mRollerRequestTLS.set(this );
129: if (mRequest.getContextPath().equals("/atom")) {
130: return; // Atom servlet request needs no init
131: }
132:
133: // Bind persistence session to authenticated user, if we have one
134: RollerContext rctx = RollerContext.getRollerContext();
135: Authenticator auth = rctx.getAuthenticator();
136: String userName = auth.getAuthenticatedUserName(mRequest);
137: if (userName != null) {
138: UserManager userMgr = RollerFactory.getRoller()
139: .getUserManager();
140: UserData currentUser = userMgr.getUserByUserName(userName);
141: // TODO: possible fix for backend refactoryings
142: //RollerFactory.getRoller().setUser(currentUser);
143: }
144:
145: // path info may be null, (e.g. on JSP error page)
146: mPathInfo = mRequest.getPathInfo();
147: mPathInfo = (mPathInfo != null) ? mPathInfo : "";
148:
149: String[] pathInfo = StringUtils.split(mPathInfo, "/");
150: if (pathInfo.length > 0) {
151: // Parse pathInfo and throw exception if it is invalid
152: if (!"j_security_check".equals(pathInfo[0])) {
153: parsePathInfo(pathInfo);
154: return;
155: }
156: }
157:
158: // Parse user, page, and entry from request params if possible
159: parseRequestParams();
160: }
161:
162: public String toString() {
163: StringBuffer sb = new StringBuffer();
164: sb.append("[");
165: sb.append(getRequestURL());
166: sb.append(", ");
167: sb.append(getRefererURL());
168: sb.append("]");
169: return sb.toString();
170: }
171:
172: //------------------------------------------------------------------------
173: /**
174: * Bind persistence session to specific user.
175: */
176: private void bindUser() throws RollerException {
177: }
178:
179: //------------------------------------------------------------------------
180: /** Parse pathInfo and throw exception if it is invalid */
181: private void parsePathInfo(String[] pathInfo)
182: throws RollerException {
183: try {
184: // If there is any path info, it must be in one of the
185: // below formats or the request is considered to be invalid.
186: //
187: // /username
188: // /username/datestring
189: // /username/pagelink
190: // /username/pagelink/datestring
191: // /username/pagelink/anchor (specific entry)
192: // /username/pagelink/datestring/anchor (specific entry)
193: Roller roller = RollerFactory.getRoller();
194: UserManager userMgr = roller.getUserManager();
195: mWebsite = userMgr.getWebsiteByHandle(pathInfo[0]);
196: if (mWebsite != null) {
197: if (pathInfo.length == 1) {
198: // we have the /username form of URL
199: mPage = mWebsite.getDefaultPage();
200: } else if (pathInfo.length == 2) {
201: mDate = parseDate(pathInfo[1]);
202: if (mDate == null) // pre-jdk1.4 --> || mDate.getYear() <= 70 )
203: {
204: // we have the /username/pagelink form of URL
205: mPageLink = pathInfo[1];
206: mPage = mWebsite.getPageByLink(pathInfo[1]);
207: } else {
208: // we have the /username/datestring form of URL
209: mDateString = pathInfo[1];
210: mPage = mWebsite.getDefaultPage();
211: if (pathInfo[1].length() == 8) {
212: mIsDaySpecified = true;
213: } else {
214: mIsMonthSpecified = true;
215: }
216: }
217: } else if (pathInfo.length == 3) {
218: mPageLink = pathInfo[1];
219: mPage = mWebsite.getPageByLink(pathInfo[1]);
220:
221: mDate = parseDate(pathInfo[2]);
222: if (mDate == null) // pre-jdk1.4 --> || mDate.getYear() <= 70 )
223: {
224: // we have the /username/pagelink/anchor form of URL
225: try {
226: WeblogManager weblogMgr = roller
227: .getWeblogManager();
228: mWeblogEntry = weblogMgr
229: .getWeblogEntryByAnchor(mWebsite,
230: pathInfo[2]);
231: } catch (Exception e) {
232: mLogger.debug("Can't find entry by anchor",
233: e);
234: }
235: } else {
236: // we have the /username/pagelink/datestring form of URL
237: mDateString = pathInfo[2];
238: if (pathInfo[1].length() == 8) {
239: mIsDaySpecified = true;
240: } else {
241: mIsMonthSpecified = true;
242: }
243: }
244: } else if (pathInfo.length == 4) {
245: // we have the /username/pagelink/datestring/anchor form of URL
246: mPageLink = pathInfo[1];
247: mPage = mWebsite.getPageByLink(pathInfo[1]);
248:
249: mDate = parseDate(pathInfo[2]);
250: mDateString = pathInfo[2];
251: if (pathInfo[1].length() == 8) {
252: mIsDaySpecified = true;
253: } else {
254: mIsMonthSpecified = true;
255: }
256:
257: // we have the /username/pagelink/date/anchor form of URL
258: WeblogManager weblogMgr = RollerFactory.getRoller()
259: .getWeblogManager();
260: mWeblogEntry = weblogMgr.getWeblogEntryByAnchor(
261: mWebsite, pathInfo[3]);
262: }
263: }
264: if (mDate == null && mWeblogEntry != null) {
265: mDate = mWeblogEntry.getPubTime();
266: //mDateString = DateUtil.format8chars(mDate);
267: }
268: } catch (Exception ignored) {
269: mLogger.debug("Exception parsing pathInfo", ignored);
270: }
271:
272: // NOTE: let the caller handle missing website/page instead
273: if (mWebsite == null || mPage == null) {
274: String msg = "Invalid pathInfo: "
275: + StringUtils.join(pathInfo, "|");
276: throw new RollerException(msg);
277: }
278: }
279:
280: //------------------------------------------------------------------------
281: /** Parse user, page, and entry from request params if possible */
282: private void parseRequestParams() {
283: try {
284: // No path info means that we need to parse request params
285:
286: // First, look for user in the request params
287: UserManager userMgr = RollerFactory.getRoller()
288: .getUserManager();
289: String userName = mRequest
290: .getParameter(RequestConstants.USERNAME);
291: if (userName == null) {
292: // then try remote user
293: userName = mRequest.getRemoteUser();
294: }
295:
296: String handle = mRequest
297: .getParameter(RequestConstants.WEBLOG);
298: String websiteid = mRequest
299: .getParameter(RequestConstants.WEBLOG_ID);
300: FolderData folder = getFolder();
301: if (handle != null && mWebsite == null) {
302: mWebsite = userMgr.getWebsiteByHandle(handle);
303: } else if (websiteid != null && mWebsite == null) {
304: mWebsite = userMgr.getWebsite(websiteid);
305: } else if (folder != null && mWebsite == null) {
306: mWebsite = folder.getWebsite();
307: }
308:
309: // Look for page ID in request params
310: String pageId = mRequest
311: .getParameter(RequestConstants.PAGE_ID);
312: if (pageId != null) {
313: mPage = userMgr.getPage(pageId);
314: } else if (mWebsite != null) {
315: mPage = mWebsite.getDefaultPage();
316: }
317:
318: // Look for day in request params
319: // no longer used
320: // String daystr = mRequest.getParameter(RollerConstants.WEBLOGDAY);
321: // if ( daystr != null )
322: // {
323: // mDate = parseDate(daystr);
324: // if ( mDate != null )
325: // {
326: // // we have the /username/datestring form of URL
327: // mDateString = daystr;
328: // mIsDaySpecified = true;
329: // }
330: // }
331: } catch (Exception ignored) {
332: mLogger.debug("Exception parsing request params", ignored);
333: }
334: }
335:
336: //------------------------------------------------------------------------
337: /** Get HttpServletmRequest that is wrapped by this RollerRequest */
338: public PageContext getPageContext() {
339: return mPageContext;
340: }
341:
342: public void setPageContext(PageContext p) {
343: mPageContext = p;
344: }
345:
346: //------------------------------------------------------------------------
347: /** Get HttpServletmRequest that is wrapped by this RollerRequest */
348: public HttpServletRequest getRequest() {
349: return mRequest;
350: }
351:
352: //------------------------------------------------------------------------
353: /**
354: * Get the RollerRequest object that is stored in the request. Creates
355: * RollerRequest if one not found in mRequest.
356: */
357: public static RollerRequest getRollerRequest(HttpServletRequest r,
358: ServletContext ctx) throws RollerException {
359: RollerRequest ret = (RollerRequest) r
360: .getAttribute(ROLLER_REQUEST);
361: if (ret == null) {
362: ret = new RollerRequest(r, ctx);
363: r.setAttribute(ROLLER_REQUEST, ret);
364: }
365: return ret;
366: }
367:
368: //------------------------------------------------------------------------
369: /**
370: * Get the RollerRequest object that is stored in the request. Creates
371: * RollerRequest if one not found in mRequest.
372: */
373: public static RollerRequest getRollerRequest(HttpServletRequest r) {
374: try {
375: return getRollerRequest(r, RollerContext
376: .getServletContext());
377: } catch (Exception e) {
378: mLogger.debug("Unable to create a RollerRequest", e);
379: }
380: return null;
381: }
382:
383: //------------------------------------------------------------------------
384: /**
385: * Get the RollerRequest object that is stored in the request. Creates
386: * RollerRequest if one not found in mRequest.
387: */
388: public static RollerRequest getRollerRequest(PageContext p)
389: throws RollerException {
390:
391: HttpServletRequest r = (HttpServletRequest) p.getRequest();
392: RollerRequest ret = (RollerRequest) r
393: .getAttribute(ROLLER_REQUEST);
394: if (ret == null) {
395: ret = new RollerRequest(p);
396: r.setAttribute(ROLLER_REQUEST, ret);
397: } else {
398: ret.setPageContext(p);
399: }
400: return ret;
401: }
402:
403: //------------------------------------------------------------------------
404: /**
405: * Get RollerRequest object for the current thread using EVIL MAGIC,
406: * do not use unless you absolutely, positively, cannot use on of the
407: * getRollerRequest() methods.
408: */
409: public static RollerRequest getRollerRequest() {
410: return (RollerRequest) mRollerRequestTLS.get();
411: }
412:
413: //------------------------------------------------------------------------
414: /**
415: * Get the RollerRequest object that is stored in the requeset.
416: * Creates RollerRequest if one not found in mRequest.
417: */
418: public ServletContext getServletContext() {
419: return mContext;
420: }
421:
422: //-----------------------------------------------------------------------------
423:
424: public boolean isDaySpecified() {
425: return mIsDaySpecified;
426: }
427:
428: public boolean isMonthSpecified() {
429: return mIsMonthSpecified;
430: }
431:
432: //--------------------------------------------------- Date specified by request
433:
434: /**
435: * Gets the date specified by the request, or null.
436: * @return Date
437: */
438: public Date getDate() {
439: return getDate(false);
440: }
441:
442: /**
443: * Gets the date specified by the request
444: * @param orToday If no date specified, then use today's date.
445: * @return Date
446: */
447: public Date getDate(boolean orToday) {
448: Date ret = null;
449: if (mDate != null) {
450: ret = mDate;
451: } else if (orToday) {
452: ret = getToday();
453: }
454: return ret;
455: }
456:
457: /**
458: * Gets the current date based on Website's Locale & Timezone.
459: * @return
460: */
461: private Date getToday() {
462: Calendar todayCal = Calendar.getInstance();
463: if (this .getWebsite() != null) {
464: todayCal = Calendar.getInstance(this .getWebsite()
465: .getTimeZoneInstance(), this .getWebsite()
466: .getLocaleInstance());
467: }
468: todayCal.setTime(new Date());
469: return todayCal.getTime();
470: }
471:
472: /*
473: * Gets the YYYYMMDD or YYYYMM date string specified by the request, or null.
474: * @return String
475: */
476: public String getDateString1() {
477: return mDateString;
478: }
479:
480: //------------------------------------------------------------------------
481: /**
482: * Gets the path-info specified by the request, or null.
483: * @return String
484: */
485: public String getPathInfo() {
486: return mPathInfo;
487: }
488:
489: //------------------------------------------------------------------------
490: /**
491: * Gets the page link name specified by the request, or null.
492: * @return String
493: */
494: public String getPageLink() {
495: return mPageLink;
496: }
497:
498: public int getWeblogEntryCount() {
499: // Get count of entries to return, or 20 if null
500: int count = 20;
501: if (mRequest.getParameter("count") != null) {
502: count = Utilities.stringToInt(mRequest
503: .getParameter("count"));
504: if (count == 0 || count > 50) {
505: count = 20;
506: }
507: }
508: return count;
509: }
510:
511: //------------------------------------------------------------------------
512: /**
513: * Gets the BookmarkData specified by the request, or null.
514: * @return BookmarkData
515: */
516: public BookmarkData getBookmark() {
517: if (mBookmark == null) {
518: String id = getFromRequest(RequestConstants.BOOKMARK_ID);
519: if (id != null) {
520: try {
521: mBookmark = RollerFactory.getRoller()
522: .getBookmarkManager().getBookmark(id);
523: } catch (RollerException e) {
524: mLogger.error("Getting bookmark from request", e);
525: }
526: }
527: }
528: return mBookmark;
529: }
530:
531: //------------------------------------------------------------------------
532: /**
533: * Gets the WeblogCategoryData specified by the request, or null.
534: * @return
535: */
536: public WeblogCategoryData getWeblogCategory() {
537: if (mWeblogCategory == null) {
538: String id = getFromRequest(RequestConstants.WEBLOGCATEGORY_ID);
539: if (id != null) {
540: try {
541: mWeblogCategory = RollerFactory.getRoller()
542: .getWeblogManager().getWeblogCategory(id);
543: } catch (RollerException e) {
544: mLogger
545: .error(
546: "Getting weblog category by id from request",
547: e);
548: }
549: } else if (StringUtils
550: .isNotEmpty(id = getFromRequest(RequestConstants.WEBLOGCATEGORY))) {
551: try {
552: mWeblogCategory = RollerFactory.getRoller()
553: .getWeblogManager()
554: .getWeblogCategoryByPath(getWebsite(),
555: null, id);
556: } catch (RollerException e) {
557: mLogger
558: .error(
559: "Getting weblog category by name from request",
560: e);
561: }
562: }
563: }
564: return mWeblogCategory;
565: }
566:
567: //------------------------------------------------------------------------
568: /**
569: * Gets the FolderData specified by the request, or null.
570: * @return FolderData
571: */
572: public FolderData getFolder() {
573: FolderData folder = null;
574: //if ( folder == null )
575: //{
576: String id = getFromRequest(RequestConstants.FOLDER_ID);
577: if (id != null) {
578: try {
579: folder = RollerFactory.getRoller().getBookmarkManager()
580: .getFolder(id);
581: } catch (RollerException e) {
582: mLogger.error("Getting folder from request", e);
583: }
584: }
585: //}
586: return folder;
587: }
588:
589: //------------------------------------------------------------------------
590: /**
591: * Gets the WeblogTemplate specified by the request, or null.
592: * @return WeblogTemplate
593: */
594: public Template getPage() {
595: if (mPage == null) {
596: String id = getFromRequest(RequestConstants.PAGE_ID);
597: if (id != null) {
598: try {
599: mPage = RollerFactory.getRoller().getUserManager()
600: .getPage(id);
601: } catch (RollerException e) {
602: mLogger.error("Getting page from request", e);
603: }
604: }
605: }
606: return mPage;
607: }
608:
609: /**
610: * Allow comment servlet to inject page that it has chosen.
611: */
612: public void setPage(org.apache.roller.pojos.Template page) {
613: mPage = page;
614: }
615:
616: //------------------------------------------------------------------------
617: /**
618: * Gets the Request URL specified by the request, or null.
619: * @return String
620: */
621: public String getRequestURL() {
622: return mRequest.getRequestURL().toString();
623: }
624:
625: //------------------------------------------------------------------------
626:
627: /**
628: * Gets the Referer URL specified by the request, or null.
629: * @return String
630: */
631: public String getRefererURL() {
632: return mRequest.getHeader("referer");
633: }
634:
635: /**
636: * Gets the WebsiteData specified in the path info of the request URI, this is
637: * NOT the same thing as the "current website" (i.e. the one that the session's
638: * authenticated user is currently editing).
639: * @return WebsiteData object specified by request URI.
640: */
641: public WebsiteData getWebsite() {
642: return mWebsite;
643: }
644:
645: public void setWebsite(WebsiteData wd) {
646: mWebsite = wd;
647: }
648:
649: /**
650: * Gets the WeblogEntryData specified by the request, or null.
651: *
652: * Why is this done lazily in the parseRequestParameters() method?
653: *
654: * Because: that method is called from init(), which is called from
655: * a ServletFilter, and sometimes request parameters are not available
656: * in a ServletFiler. They ARE available when the URL points to a JSP,
657: * but they ARE NOT available when the URL points to the PageServlet.
658: * This may be a Tomcat bug, I'm not sure.
659: *
660: * @return WeblogEntryData
661: */
662: public WeblogEntryData getWeblogEntry() {
663: if (mWeblogEntry == null) {
664: // Look for anchor or entry ID that identifies a specific entry
665: String anchor = mRequest
666: .getParameter(RequestConstants.ANCHOR);
667: if (anchor == null)
668: anchor = mRequest.getParameter(RequestConstants.ANCHOR);
669: String entryid = mRequest
670: .getParameter(RequestConstants.WEBLOGENTRY_ID);
671: if (entryid == null) {
672: entryid = (String) mRequest
673: .getAttribute(RequestConstants.WEBLOGENTRY_ID);
674: }
675: try {
676: if (entryid != null) {
677: WeblogManager weblogMgr = RollerFactory.getRoller()
678: .getWeblogManager();
679: mWeblogEntry = weblogMgr.getWeblogEntry(entryid);
680:
681: // We can use entry to find the website, if we don't have one
682: if (mWeblogEntry != null && mWebsite == null) {
683: mWebsite = mWeblogEntry.getWebsite();
684: }
685: } else if (mWebsite != null && anchor != null) {
686: WeblogManager weblogMgr = RollerFactory.getRoller()
687: .getWeblogManager();
688: mWeblogEntry = weblogMgr.getWeblogEntryByAnchor(
689: mWebsite, anchor);
690: }
691: } catch (RollerException e) {
692: mLogger.error("EXCEPTION getting weblog entry", e);
693: mLogger.error("anchor=" + anchor);
694: mLogger.error("entryid=" + entryid);
695: }
696: if (mDate == null && mWeblogEntry != null) {
697: mDate = mWeblogEntry.getPubTime();
698: mDateString = DateUtil.format8chars(mDate);
699: }
700: }
701: return mWeblogEntry;
702: }
703:
704: //-----------------------------------------------------------------------------
705:
706: /** Get attribute from mRequest, and if that fails try session */
707: private String getFromRequest(String key) {
708: String ret = (String) mRequest.getAttribute(key);
709: if (ret == null) {
710: ret = mRequest.getParameter(key);
711: if (ret == null && mRequest.getSession(false) != null) {
712: ret = (String) mRequest.getSession().getAttribute(key);
713: }
714: }
715: return ret;
716: }
717:
718: private Date parseDate(String dateString) {
719: Date ret = null;
720: if (dateString != null && dateString.length() == 8
721: && StringUtils.isNumeric(dateString)) {
722: ParsePosition pos = new ParsePosition(0);
723: ret = m8charDateFormat.parse(dateString, pos);
724:
725: // make sure the requested date is not in the future
726: Date today = getToday();
727: if (ret.after(today))
728: ret = today;
729:
730: // Do this later, once we know what timezone to use
731: // ret = DateUtil.getEndOfDay(ret);
732: }
733: if (dateString != null && dateString.length() == 6
734: && StringUtils.isNumeric(dateString)) {
735: ParsePosition pos = new ParsePosition(0);
736: ret = m6charDateFormat.parse(dateString, pos);
737:
738: // make sure the requested date is not in the future
739: Date today = getToday();
740: if (ret.after(today))
741: ret = today;
742:
743: // Do this later, once we know what timezone to use
744: // ret = DateUtil.getEndOfMonth(ret);
745: }
746: return ret;
747: }
748:
749: /**
750: * @see org.apache.roller.pojos.ParsedRequest#isLinkbackEnabled()
751: */
752: public boolean isEnableLinkback() {
753: return RollerRuntimeConfig
754: .getBooleanProperty("site.linkbacks.enabled");
755: }
756:
757: }
|