001: package org.tigris.scarab.tools;
002:
003: /* ================================================================
004: * Copyright (c) 2000-2002 CollabNet. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are
008: * met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: *
017: * 3. The end-user documentation included with the redistribution, if
018: * any, must include the following acknowlegement: "This product includes
019: * software developed by Collab.Net <http://www.Collab.Net/>."
020: * Alternately, this acknowlegement may appear in the software itself, if
021: * and wherever such third-party acknowlegements normally appear.
022: *
023: * 4. The hosted project names must not be used to endorse or promote
024: * products derived from this software without prior written
025: * permission. For written permission, please contact info@collab.net.
026: *
027: * 5. Products derived from this software may not use the "Tigris" or
028: * "Scarab" names nor may "Tigris" or "Scarab" appear in their names without
029: * prior written permission of Collab.Net.
030: *
031: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
032: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
033: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
034: * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
035: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
036: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
037: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
038: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
039: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
040: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
041: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
042: *
043: * ====================================================================
044: *
045: * This software consists of voluntary contributions made by many
046: * individuals on behalf of Collab.Net.
047: */
048:
049: import java.util.Date;
050: import java.util.Calendar;
051: import java.util.List;
052: import java.util.ArrayList;
053: import java.util.Set;
054: import java.util.StringTokenizer;
055: import java.util.Enumeration;
056: import java.util.Vector;
057:
058: import org.apache.commons.lang.StringUtils;
059: import org.apache.log4j.Logger;
060: import org.apache.fulcrum.TurbineServices;
061: import org.apache.fulcrum.security.TurbineSecurity;
062: import org.apache.fulcrum.security.entity.User;
063: import org.apache.fulcrum.velocity.TurbineVelocityService;
064: import org.apache.fulcrum.velocity.VelocityService;
065: import org.apache.oro.text.perl.Perl5Util;
066: import org.apache.turbine.services.pull.ApplicationTool;
067:
068: import org.apache.velocity.app.FieldMethodizer;
069: import org.radeox.api.engine.RenderEngine;
070: import org.radeox.api.engine.context.RenderContext;
071: import org.radeox.engine.context.BaseRenderContext;
072:
073: import org.tigris.scarab.notification.ActivityType;
074: import org.tigris.scarab.om.AttributePeer;
075: import org.tigris.scarab.om.IssueTypePeer;
076:
077: import org.tigris.scarab.om.NotificationFilter;
078: import org.tigris.scarab.om.NotificationFilterManager;
079: import org.tigris.scarab.om.NotificationFilterPeer;
080: import org.tigris.scarab.om.ScarabUser;
081: import org.tigris.scarab.om.ScarabUserImplPeer;
082: import org.tigris.scarab.om.GlobalParameterManager;
083: import org.tigris.scarab.om.ModuleManager;
084: import org.tigris.scarab.om.Module;
085: import org.tigris.scarab.om.MITListManager;
086: import org.tigris.scarab.services.security.ScarabSecurity;
087: import org.tigris.scarab.tools.radeox.ScarabRenderEngine;
088: import org.tigris.scarab.util.ReferenceInsertionFilter;
089: import org.tigris.scarab.workflow.Workflow;
090: import org.tigris.scarab.workflow.WorkflowFactory;
091: import org.tigris.scarab.util.IssueIdParser;
092: import org.tigris.scarab.util.Log;
093: import org.tigris.scarab.util.ScarabException;
094: import org.tigris.scarab.util.SkipFiltering;
095: import org.tigris.scarab.util.SimpleSkipFiltering;
096: import org.tigris.scarab.util.ScarabLink;
097: import org.tigris.scarab.util.ScarabUtil;
098:
099: import org.apache.torque.util.Criteria;
100: import org.apache.torque.TorqueException;
101:
102: import org.apache.turbine.Turbine;
103:
104: /**
105: * This scope is an object that is made available as a global
106: * object within the system.
107: * This object must be thread safe as multiple
108: * requests may access it at the same time. The object is made
109: * available in the context as: $scarabG
110: * <p>
111: * The design goals of the Scarab*API is to enable a <a
112: * href="http://jakarta.apache.org/turbine/pullmodel.html">pull based
113: * methodology</a> to be implemented.
114: *
115: * @author <a href="mailto:jon@collab.net">Jon S. Stevens</a>
116: * @author <a href="mailto:dr@bitonic.com">Douglas B. Robertson</a>
117: * @version $Id: ScarabGlobalTool.java 10198 2006-07-03 23:33:30Z dabbous $
118: */
119: public class ScarabGlobalTool implements ApplicationTool {
120: private static int moduleCodeLength = 0;
121:
122: private static final String REGEX_URL = "s%\\b(?:[hH][tT]{2}[pP][sS]{0,1}|[fF][tT][pP]):[^ \\t\\n<>\"]+[\\w/]*%<a href=\"$0\">$0</a>%g";
123: private static final String REGEX_MAILTO = "s%\\b(?:([mM][aA][iI][lL][tT][oO])):([^ \\t\\n<>\"]+[\\w/])*%<a href=\"$0\">$2</a>%g";
124: private static final String REGEX_NEWLINETOBR = "s%\\n%<br />%g";
125:
126: private static Perl5Util perlUtil = new Perl5Util();
127:
128: private static final Logger LOG = Logger
129: .getLogger("org.tigris.scarab");
130:
131: /**
132: * holds the Scarab constants
133: */
134: private FieldMethodizer constant = null;
135:
136: /**
137: * holds the Scarab security permission constants
138: */
139: private FieldMethodizer security = null;
140:
141: /**
142: * holds the Scarab parameter name constants
143: */
144: private FieldMethodizer parameterName = null;
145:
146: private static final String BUILD_VERSION = Turbine
147: .getConfiguration().getString("scarab.build.version", "");
148:
149: private static RenderContext context = new BaseRenderContext();
150: private static RenderEngine engine = new ScarabRenderEngine();
151:
152: public void init(Object data) {
153: }
154:
155: public void refresh() {
156: }
157:
158: /**
159: * Constructor does initialization stuff
160: */
161: public ScarabGlobalTool() {
162: constant = new FieldMethodizer(
163: "org.tigris.scarab.util.ScarabConstants");
164: security = new FieldMethodizer(
165: "org.tigris.scarab.services.security.ScarabSecurity");
166: parameterName = new FieldMethodizer(
167: "org.tigris.scarab.om.GlobalParameter");
168: }
169:
170: /**
171: * returns Scarab's build version.
172: */
173: public String getBuildVersion() {
174: return BUILD_VERSION;
175: }
176:
177: /**
178: * holds the Scarab constants. it will be available to the template system
179: * as $scarabG.Constant.CONSTANT_NAME.
180: */
181: public FieldMethodizer getConstant() {
182: return constant;
183: }
184:
185: /**
186: * holds the Scarab permission constants. It will be available to
187: * the template system as $scarabG.PERMISSION_NAME.
188: */
189: public FieldMethodizer getPermission() {
190: return security;
191: }
192:
193: /**
194: * holds the names of parameters that are configurable through the ui.
195: */
196: public FieldMethodizer getParameterName() {
197: return parameterName;
198: }
199:
200: public String replace(String text, String a, String b) {
201: return StringUtils.replace(text, a, b);
202: }
203:
204: public GlobalParameterManager getParameter() {
205: return GlobalParameterManager.getManager();
206: }
207:
208: /**
209: * Returns a list of all the permissions in use by scarab.
210: *
211: * @return a <code>List</code> of <code>String</code>s
212: */
213: public List getAllPermissions() {
214: return ScarabSecurity.getAllPermissions();
215: }
216:
217: /**
218: * Gets a List of all of the data (non-user) Attribute objects.
219: */
220: public List getAllAttributes() throws Exception {
221: return AttributePeer.getAttributes();
222: }
223:
224: /**
225: * Gets a List of all of the Attribute objects by type.
226: */
227: public List getAttributes(String attributeType) throws Exception {
228: return AttributePeer.getAttributes(attributeType, false);
229: }
230:
231: /**
232: * Gets a List of all of the data (non-user) Attribute objects.
233: * Passes in sort criteria.
234: */
235: public List getAllAttributes(String attributeType,
236: boolean includeDeleted, String sortColumn,
237: String sortPolarity) throws Exception {
238: return AttributePeer.getAttributes(attributeType,
239: includeDeleted, sortColumn, sortPolarity);
240: }
241:
242: /**
243: * Gets a List of all of the data (non-user) Attribute objects.
244: * Passes in sort criteria.
245: */
246: public List getAllAttributes(String sortColumn, String sortPolarity)
247: throws Exception {
248: return AttributePeer.getAttributes(sortColumn, sortPolarity);
249: }
250:
251: /**
252: * Gets a List of all of user Attributes.
253: */
254: public List getUserAttributes() throws Exception {
255: return AttributePeer.getAttributes("user");
256: }
257:
258: /**
259: * Gets a List of all of the Attribute objects.
260: */
261: public List getUserAttributes(String sortColumn, String sortPolarity)
262: throws Exception {
263: return AttributePeer.getAttributes("user", false, sortColumn,
264: sortPolarity);
265: }
266:
267: /**
268: * Gets a List of all of the Attribute objects.
269: */
270: public List getUserAttributes(boolean includeDeleted,
271: String sortColumn, String sortPolarity) throws Exception {
272: return AttributePeer.getAttributes("user", includeDeleted,
273: sortColumn, sortPolarity);
274: }
275:
276: /**
277: * Gets a List of all of user Attribute objects.
278: */
279: public List getAttributes(String attributeType,
280: boolean includeDeleted, String sortColumn,
281: String sortPolarity) throws Exception {
282: return AttributePeer.getAttributes(attributeType,
283: includeDeleted, sortColumn, sortPolarity);
284: }
285:
286: public List getAllIssueTypes() throws Exception {
287: return IssueTypePeer.getAllIssueTypes(false, "name", "asc");
288: }
289:
290: /**
291: * gets a list of all Issue Types
292: */
293: public List getAllIssueTypes(boolean deleted) throws Exception {
294: return IssueTypePeer.getAllIssueTypes(deleted, "name", "asc");
295: }
296:
297: /**
298: * Gets a List of all of the Attribute objects.
299: */
300: public List getAllIssueTypes(boolean deleted, String sortColumn,
301: String sortPolarity) throws Exception {
302: return IssueTypePeer.getAllIssueTypes(deleted, sortColumn,
303: sortPolarity);
304: }
305:
306: /**
307: * Get the list of available activityType codes.
308: * @return
309: */
310: public List getAllNotificationTypeCodes() {
311: Set activityTypes = ActivityType.getActivityTypeCodes();
312: List result = new Vector(activityTypes);
313: return result;
314: }
315:
316: /**
317: * Remap Activity code to resource id. Necessary due to
318: * incompatible name conventions.
319: * @param code
320: * @return
321: */
322: public String getActivityTypeLabelResource(String code) {
323: return ActivityType.getResourceId(code);
324: }
325:
326: /**
327: * Return the list of available NotificationFilters for
328: * the given user in the given module
329: * @param moduleId
330: * @param userId
331: * @param activityCode
332: * @return
333: * @throws TorqueException
334: */
335: public List getCustomization(Object moduleId, Object userId,
336: Object activityCode) throws TorqueException {
337: NotificationFilterPeer nfp = new NotificationFilterPeer();
338: List result = nfp.getCustomization(moduleId, userId,
339: activityCode);
340: return result;
341: }
342:
343: public static NotificationFilter getNotificationFilter(
344: Integer moduleId, Integer userId, String activityCode)
345: throws ScarabException {
346: NotificationFilter result = NotificationFilterManager
347: .getNotificationFilter(moduleId, userId, activityCode);
348: return result;
349: }
350:
351: /**
352: * Makes the workflow tool accessible.
353: * @throws ScarabException
354: */
355: public static Workflow getWorkflow() throws ScarabException {
356: return WorkflowFactory.getInstance();
357: }
358:
359: /**
360: * Returns a List of users based on the given search criteria. This method
361: * is an overloaded function which returns an unsorted list of users.
362: *
363: * @param searchField the name of the database attribute to search on
364: * @param searchCriteria the search criteria to use within the LIKE command
365: * @return a List of users matching the specifed criteria
366: *
367: */
368: public List getSearchUsers(String searchField, String searchCriteria)
369: throws Exception {
370: return (getSearchUsers(searchField, searchCriteria, null, null));
371: }
372:
373: /**
374: * Returns a List of users based on the given search criteria and orders
375: * the list by the specified field. The method will use the LIKE
376: * SQL command and perform a search as such (assuming 'doug' is
377: * specified as the search criteria:
378: * <code>WHERE some_field LIKE '%doug%'</code>
379: *
380: * @param searchField the name of the database attribute to search on
381: * @param searchCriteria the search criteria to use within the LIKE command
382: * @param orderByField the name of the database attribute to order the list by
383: * @param ascOrDesc either "ASC" of "DESC" specifying the order to sort in
384: * @return a List of users matching the specifed criteria
385: */
386: /**
387: * Describe <code>getSearchUsers</code> method here.
388: *
389: * @param searchField a <code>String</code> value
390: * @param searchCriteria a <code>String</code> value
391: * @param orderByField a <code>String</code> value
392: * @param ascOrDesc a <code>String</code> value
393: * @return a <code>List</code> value
394: * @exception Exception if an error occurs
395: */
396: public List getSearchUsers(String searchField,
397: String searchCriteria, String orderByField, String ascOrDesc)
398: throws Exception {
399: ArrayList userSearchList = new ArrayList();
400: String lSearchField = "";
401: String lOrderByField = "";
402:
403: Criteria criteria = new Criteria();
404:
405: // add the input from the user
406: if (searchCriteria != null && searchCriteria.length() > 0) {
407: if (searchField.equals("FIRST_NAME")) {
408: lSearchField = ScarabUser.FIRST_NAME;
409: } else if (searchField.equals("LAST_NAME")) {
410: lSearchField = ScarabUser.LAST_NAME;
411: } else if (searchField.equals("LOGIN_NAME")) {
412: lSearchField = ScarabUser.USERNAME;
413: } else {
414: lSearchField = ScarabUser.EMAIL;
415: }
416:
417: // FIXME: Probably shouldn't be using ScarabUserPeerImpl here
418: // What should we do to get the right table name?
419: lSearchField = ScarabUserImplPeer.getTableName() + '.'
420: + lSearchField;
421:
422: criteria = criteria.add(lSearchField,
423: (Object) ('%' + searchCriteria.trim() + '%'),
424: Criteria.LIKE);
425: }
426:
427: // sort the results
428: if (orderByField != null && orderByField.length() > 0) {
429: if (orderByField.equals("FIRST_NAME")) {
430: lOrderByField = ScarabUser.FIRST_NAME;
431: } else if (orderByField.equals("LAST_NAME")) {
432: lOrderByField = ScarabUser.LAST_NAME;
433: } else if (orderByField.equals("LOGIN_NAME")) {
434: lOrderByField = ScarabUser.USERNAME;
435: } else {
436: lOrderByField = ScarabUser.EMAIL;
437: }
438:
439: // FIXME: Probably shouldn't be using ScarabUserPeerImpl here
440: // What should we do to get the right table name?
441: lOrderByField = ScarabUserImplPeer.getTableName() + '.'
442: + lOrderByField;
443:
444: if (ascOrDesc != null && ascOrDesc.equalsIgnoreCase("DESC")) {
445: criteria = criteria
446: .addDescendingOrderByColumn(lOrderByField);
447: } else {
448: criteria = criteria
449: .addAscendingOrderByColumn(lOrderByField);
450: }
451: }
452:
453: User[] tempUsers = TurbineSecurity.getUsers(criteria);
454: for (int i = 0; i < tempUsers.length; i++) {
455: userSearchList.add(i, tempUsers[i]);
456: }
457: return (userSearchList);
458: }
459:
460: /**
461: * Create a list of Modules from the given list of issues. Each
462: * Module in the list of issues will only occur once in the list of
463: * Modules.
464: */
465: public List getModulesFromIssueList(List issues)
466: throws TorqueException {
467: return ModuleManager.getInstancesFromIssueList(issues);
468: }
469:
470: public MITListManager getMITListManager() {
471: return MITListManager.getManager();
472: }
473:
474: /**
475: * Get a new Date object initialized to the current time.
476: * @return a <code>Date</code> value
477: */
478: public Date getNow() {
479: return new Date();
480: }
481:
482: /**
483: * Creates a new array with elements reversed from the given array.
484: *
485: * @param a the orginal <code>Object[]</code>
486: * @return a new <code>Object[]</code> with values reversed from the
487: * original
488: */
489: public Object[] reverse(Object[] a) {
490: Object[] b = new Object[a.length];
491: for (int i = a.length - 1; i >= 0; i--) {
492: b[a.length - 1 - i] = a[i];
493: }
494: return b;
495: }
496:
497: /**
498: * Creates a new <code>List</code> with elements reversed from the
499: * given <code>List</code>.
500: *
501: * @param a the orginal <code>List</code>
502: * @return a new <code>List</code> with values reversed from the
503: * original
504: */
505: public List reverse(List a) {
506: int size = a.size();
507: List b = new ArrayList(size);
508: for (int i = size - 1; i >= 0; i--) {
509: b.add(a.get(i));
510: }
511: return b;
512: }
513:
514: /**
515: * Creates a view of the portion of the given
516: * <code>List</code> between the specified <code>fromIndex</code>, inclusive, and
517: * <code>toIndex</code>, exclusive.
518: * The list returned by this method is backed by the original, so changes
519: * to either affect the other.
520: *
521: * @param a the orginal <code>List</code>
522: * @param fromIndex the start index of the returned subset
523: * @param toIndex the end index of the returned subset
524: * @return a derived <code>List</code> with a view of the original
525: */
526: public List subset(List a, Integer fromIndex, Integer toIndex) {
527: int from = Math.min(fromIndex.intValue(), a.size());
528: from = Math.max(from, 0);
529: int to = Math.min(toIndex.intValue(), a.size());
530: to = Math.max(to, from);
531: return a.subList(from, to);
532: }
533:
534: /**
535: * Creates a new array with a view of the portion of the given array
536: * between the specified fromIndex, inclusive, and toIndex, exclusive
537: *
538: * @param a the orginal <code>Object[]</code>
539: * @param fromIndex the start index of the returned subset
540: * @param toIndex the end index of the returned subset
541: * @return a new <code>Object[]</code> with a view of the original
542: */
543: public Object[] subset(Object[] a, Integer fromIndex,
544: Integer toIndex) {
545: int from = Math.min(fromIndex.intValue(), a.length);
546: from = Math.max(from, 0);
547: int to = Math.min(toIndex.intValue(), a.length);
548: to = Math.max(to, from);
549: Object[] b = new Object[from - to];
550: for (int i = from - 1; i >= to; i--) {
551: b[i - to] = a[i];
552: }
553: return b;
554: }
555:
556: /**
557: * Velocity has no way of getting the size of an <code>Object[]</code>
558: * easily. Usually this would be done by calling obj.length
559: * but this doesn't work in Velocity.
560: * @param obj the <code>Object[]</code>
561: * @return the number of objects in the <code>Object[]</code> or -1 if obj is null
562: */
563: public int sizeOfArray(Object[] obj) {
564: return (obj == null) ? -1 : obj.length;
565: }
566:
567: public boolean isString(Object obj) {
568: return obj instanceof String;
569: }
570:
571: /**
572: * Breaks text into a list of Strings. Text is separated into tokens
573: * at characters given in delimiters. The delimiters are not part
574: * of the resulting tokens. if delimiters is empty or null, "\n" is used.
575: *
576: * @param text a <code>String</code> value
577: * @param delimiters a <code>String</code> value
578: * @return a <code>List</code> value
579: */
580: public Enumeration tokenize(String text, String delimiters) {
581: if (delimiters == null || delimiters.length() == 0) {
582: delimiters = "\n";
583: }
584:
585: if (text == null) {
586: text = "";
587: }
588:
589: StringTokenizer st = new StringTokenizer(text, delimiters);
590: return st;
591: }
592:
593: public List linkIssueIds(Module module, String text) {
594: List result = null;
595: try {
596: result = IssueIdParser.tokenizeText(module, text);
597: } catch (Exception e) {
598: // return the text as is and log the error
599: result = new ArrayList(1);
600: result.add(text);
601: Log.get().warn("Could not linkify text: " + text, e);
602: }
603: return result;
604: }
605:
606: public SkipFiltering getCommentText(String text, ScarabLink link,
607: Module currentModule) {
608: return this .textToHTML(text, link, currentModule);
609: }
610:
611: /**
612: * <p>Converts a text string to HTML by:</p>
613: * <ul>
614: * <li>replacing reserved characters with equivalent HTML entities</li>
615: * <li>adding hyperlinks for URLs</li>
616: * <li>adding hyperlinks for issue references</li>
617: * </ul>
618: * @param text The text string to convert.
619: * @param link
620: * @param currentModule The active module.
621: * @return A SkipFiltering object which contains the generated HTML.
622: */
623: public SkipFiltering textToHTML(String text, ScarabLink link,
624: Module currentModule) {
625: try {
626:
627: String renderEngine = currentModule
628: .getCommentRenderingEngine();
629: String txt;
630: if (renderEngine.equals("radeox")) {
631: txt = engine.render(text, context);
632: } else if (renderEngine.equals("html")) {
633: txt = perlUtil
634: .substitute(REGEX_URL, perlUtil.substitute(
635: REGEX_MAILTO, perlUtil.substitute(
636: REGEX_NEWLINETOBR,
637: ReferenceInsertionFilter
638: .filter(text))));
639: } else // if(renderEngine.equals("plaintext"))
640: {
641: txt = perlUtil.substitute(REGEX_URL, perlUtil
642: .substitute(REGEX_MAILTO,
643: ReferenceInsertionFilter.filter(text)));
644: }
645:
646: return new SimpleSkipFiltering(ScarabUtil.linkifyText(txt,
647: link, currentModule));
648: } catch (Exception e) {
649: return new SimpleSkipFiltering(text);
650: }
651: }
652:
653: /**
654: * Logs a message at the debug level. Useful for "I am here" type
655: * messages. The category is "org.tigris.scarab".
656: *
657: * @param s message to log
658: */
659: public void log(String s) {
660: LOG.debug(s);
661: }
662:
663: /**
664: * Logs a message at the debug level. Useful for "I am here" type
665: * messages. The category in which to log is also specified.
666: *
667: * @param category log4j Category
668: * @param s message to log
669: */
670: public void log(String category, String s) {
671: Logger.getLogger(category).debug(s);
672: }
673:
674: /**
675: * Prints a message to standard out. Useful for "I am here" type
676: * messages.
677: *
678: * @param s message to log
679: */
680: public void print(String s) {
681: System.out.println(s);
682: }
683:
684: /**
685: * Provides the site name for the top banner.
686: *
687: * @return the configured site name
688: */
689: public String getSiteName() {
690: String siteName = Turbine.getConfiguration().getString(
691: "scarab.site.name", "");
692:
693: if (siteName == null) {
694: siteName = "";
695: }
696: return siteName;
697: }
698:
699: /**
700: * Provides the site logo for the top banner.
701: *
702: * @return the configured site logo
703: */
704: public String getSiteLogo() {
705: String siteLogo = Turbine.getConfiguration().getString(
706: "scarab.site.logo", "");
707:
708: if (siteLogo == null) {
709: siteLogo = "";
710: }
711: return siteLogo;
712: }
713:
714: /**
715: * Provides the maximum number of public modules to be shown on the
716: * login screen. the number is stored in the property
717: * scarab.public.modules.display.count
718: * If no number is specified, this method returns -1
719: *
720: * @return the number specified in scarab.public.modules.display.count
721: */
722: public int getPublicModulesDisplayCount() {
723: String publicModulesDisplayCount = Turbine.getConfiguration()
724: .getString("scarab.public.modules.display.count", "-1");
725: return Integer.parseInt(publicModulesDisplayCount);
726: }
727:
728: /**
729: * Returns an <code>int</code> representation of the given
730: * <code>Object</code> whose toString method should be a valid integer.
731: * If the <code>String</code> cannot be parsed <code>0</code> is returned.
732: * @param obj the object
733: * @return the <code>int</code> representation of the <code>Object</code>
734: * if possible or <code>0</code>.
735: */
736: public int getInt(Object obj) {
737: int result = 0;
738: if (obj != null) {
739: try {
740: result = Integer.parseInt(obj.toString());
741: } catch (Exception e) {
742: Log.get().error(obj + " cannot convert to an integer.",
743: e);
744: }
745: }
746: return result;
747: }
748:
749: public int getCALENDAR_YEAR_FIELD() {
750: return Calendar.YEAR;
751: }
752:
753: public int getCALENDAR_MONTH_FIELD() {
754: return Calendar.MONTH;
755: }
756:
757: public int getCALENDAR_DAY_FIELD() {
758: return Calendar.DAY_OF_MONTH;
759: }
760:
761: public int getCALENDAR_HOUR_FIELD() {
762: return Calendar.HOUR_OF_DAY;
763: }
764:
765: public Date addApproxOneHour(Date date) {
766: date.setTime(date.getTime() + 3599999);
767: return date;
768: }
769:
770: /**
771: * Delegates to Velocity's <code>templateExists()</code> method.
772: */
773: public boolean templateExists(String template) {
774: return ((TurbineVelocityService) TurbineServices.getInstance()
775: .getService(VelocityService.SERVICE_NAME))
776: .templateExists(template);
777: }
778:
779: /**
780: * @return
781: */
782: public synchronized static int getModuleCodeLength() {
783: if (moduleCodeLength == 0) {
784: try {
785: moduleCodeLength = Integer.parseInt(Turbine
786: .getConfiguration().getString(
787: "scarab.module.code.length", "4"));
788: } catch (Exception e) {
789: e.printStackTrace();
790: moduleCodeLength = 4;
791: }
792: }
793: return moduleCodeLength;
794: }
795:
796: /**
797: * @return
798: */
799: public static int getModuleCodeLengthPadded() {
800: return getModuleCodeLength() + 6;
801: }
802:
803: /**
804: * @return Return the current turbine configuration with all keys included
805: */
806: public org.apache.commons.configuration.Configuration getTurbineConfiguration() {
807: return Turbine.getConfiguration();
808: }
809:
810: }
|