001: /*
002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/util/CmsMacroResolver.java,v $
003: * Date : $Date: 2008-03-11 08:44:20 $
004: * Version: $Revision: 1.26 $
005: *
006: * This library is part of OpenCms -
007: * the Open Source Content Management System
008: *
009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010: *
011: * This library is free software; you can redistribute it and/or
012: * modify it under the terms of the GNU Lesser General Public
013: * License as published by the Free Software Foundation; either
014: * version 2.1 of the License, or (at your option) any later version.
015: *
016: * This library is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: * Lesser General Public License for more details.
020: *
021: * For further information about Alkacon Software GmbH, please see the
022: * company website: http://www.alkacon.com
023: *
024: * For further information about OpenCms, please see the
025: * project website: http://www.opencms.org
026: *
027: * You should have received a copy of the GNU Lesser General Public
028: * License along with this library; if not, write to the Free Software
029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
030: */
031:
032: package org.opencms.util;
033:
034: import org.opencms.file.CmsObject;
035: import org.opencms.file.CmsProperty;
036: import org.opencms.file.CmsResource;
037: import org.opencms.flex.CmsFlexController;
038: import org.opencms.i18n.CmsMessageContainer;
039: import org.opencms.i18n.CmsMessages;
040: import org.opencms.main.CmsException;
041: import org.opencms.main.CmsLog;
042: import org.opencms.main.OpenCms;
043: import org.opencms.security.CmsOrganizationalUnit;
044:
045: import java.util.Arrays;
046: import java.util.Collections;
047: import java.util.HashMap;
048: import java.util.List;
049: import java.util.Map;
050:
051: import javax.servlet.jsp.PageContext;
052:
053: import org.apache.commons.logging.Log;
054:
055: /**
056: * Resolves macros in the form of <code>%(key)</code> or <code>${key}</code> in an input String.<p>
057: *
058: * Starting with OpenCms 7.0, the preferred form of a macro is <code>%(key)</code>. This is to
059: * avoid conflicts / confusion with the JSP EL, which also uses the <code>${key}</code> syntax.<p>
060: *
061: * The macro names that can be resolved depend of the context objects provided to the resolver
062: * using the <code>set...</code> methods.<p>
063: *
064: * @author Alexander Kandzior
065: * @author Thomas Weckert
066: *
067: * @version $Revision: 1.26 $
068: *
069: * @since 6.0.0
070: */
071: public class CmsMacroResolver implements I_CmsMacroResolver {
072:
073: /** The prefix indicating that the key represents an OpenCms runtime attribute. */
074: public static final String KEY_ATTRIBUTE = "attribute.";
075:
076: /** Key used to specify the description of the current organizational unit as macro value. */
077: public static final String KEY_CURRENT_ORGUNIT_DESCRIPTION = "currentou.description";
078:
079: /** Key used to specify the full qualified name of the current organizational unit as macro value. */
080: public static final String KEY_CURRENT_ORGUNIT_FQN = "currentou.fqn";
081:
082: /** Key used to specify the current time as macro value. */
083: public static final String KEY_CURRENT_TIME = "currenttime";
084:
085: /** Key used to specify the city of the current user as macro value. */
086: public static final String KEY_CURRENT_USER_CITY = "currentuser.city";
087:
088: /** Key used to specify the country of the current user as macro value. */
089: public static final String KEY_CURRENT_USER_COUNTRY = "currentuser.country";
090:
091: /** Key used to specify the display name of the current user as macro value. */
092: public static final String KEY_CURRENT_USER_DISPLAYNAME = "currentuser.displayname";
093:
094: /** Key used to specify the email address of the current user as macro value. */
095: public static final String KEY_CURRENT_USER_EMAIL = "currentuser.email";
096:
097: /** Key used to specify the first name of the current user as macro value. */
098: public static final String KEY_CURRENT_USER_FIRSTNAME = "currentuser.firstname";
099:
100: /** Key used to specify the full name of the current user as macro value. */
101: public static final String KEY_CURRENT_USER_FULLNAME = "currentuser.fullname";
102:
103: /** Key used to specify the last login date of the current user as macro value. */
104: public static final String KEY_CURRENT_USER_LASTLOGIN = "currentuser.lastlogin";
105:
106: /** Key used to specify the last name of the current user as macro value. */
107: public static final String KEY_CURRENT_USER_LASTNAME = "currentuser.lastname";
108:
109: /** Key used to specify the user name of the current user as macro value. */
110: public static final String KEY_CURRENT_USER_NAME = "currentuser.name";
111:
112: /** Key used to specify the street of the current user as macro value. */
113: public static final String KEY_CURRENT_USER_STREET = "currentuser.street";
114:
115: /** Key used to specify the zip code of the current user as macro value. */
116: public static final String KEY_CURRENT_USER_ZIP = "currentuser.zip";
117:
118: /** Key prefix used to specify the value of a localized key as macro value. */
119: public static final String KEY_LOCALIZED_PREFIX = "key.";
120:
121: /** Identifier for "magic" parameter names. */
122: public static final String KEY_OPENCMS = "opencms.";
123:
124: /** The prefix indicating that the key represents a page context object. */
125: public static final String KEY_PAGE_CONTEXT = "pageContext.";
126:
127: /** Key used to specify the project id as macro value. */
128: public static final String KEY_PROJECT_ID = "projectid";
129:
130: /** The prefix indicating that the key represents a property to be read on the current request URI. */
131: public static final String KEY_PROPERTY = "property.";
132:
133: /** The prefix indicating that the key represents a property to be read on the current element. */
134: public static final String KEY_PROPERTY_ELEMENT = "elementProperty.";
135:
136: /** Key used to specify the request encoding as macro value. */
137: public static final String KEY_REQUEST_ENCODING = "request.encoding";
138:
139: /** Key used to specify the folder of the request URI as macro value. */
140: public static final String KEY_REQUEST_FOLDER = "request.folder";
141:
142: /** Key user to specify the request locale as macro value. */
143: public static final String KEY_REQUEST_LOCALE = "request.locale";
144:
145: /** The prefix indicating that the key represents a HTTP request parameter. */
146: public static final String KEY_REQUEST_PARAM = "param.";
147:
148: /** Key used to specify the request uri as macro value. */
149: public static final String KEY_REQUEST_URI = "request.uri";
150:
151: /** Key used to specify the validation path as macro value. */
152: public static final String KEY_VALIDATION_PATH = "validation.path";
153:
154: /** Key used to specify the validation regex as macro value. */
155: public static final String KEY_VALIDATION_REGEX = "validation.regex";
156:
157: /** Key used to specify the validation value as macro value. */
158: public static final String KEY_VALIDATION_VALUE = "validation.value";
159:
160: /** Identified for "magic" parameter commands. */
161: static final String[] VALUE_NAMES_ARRAY = { "uri", // 0
162: "filename", // 1
163: "folder", // 2
164: "default.encoding", // 3
165: "remoteaddress", // 4
166: "webapp", // 5
167: "webbasepath", // 6
168: "version" // 7
169: };
170:
171: /** The "magic" commands wrapped in a List. */
172: public static final List VALUE_NAMES = Collections
173: .unmodifiableList(Arrays.asList(VALUE_NAMES_ARRAY));
174:
175: /** The log object for this class. */
176: private static final Log LOG = CmsLog
177: .getLog(CmsMacroResolver.class);
178:
179: /** A map of additional values provided by the calling class. */
180: protected Map m_additionalMacros;
181:
182: /** The OpenCms user context to use for resolving macros. */
183: protected CmsObject m_cms;
184:
185: /** The JSP's page context to use for resolving macros. */
186: protected PageContext m_jspPageContext;
187:
188: /** Indicates if unresolved macros should be kept "as is" or replaced by an empty String. */
189: protected boolean m_keepEmptyMacros;
190:
191: /** The messages resource bundle to resolve localized keys with. */
192: protected CmsMessages m_messages;
193:
194: /** The resource name to use for resolving macros. */
195: protected String m_resourceName;
196:
197: /**
198: * Adds macro delimiters to the given input,
199: * for example <code>key</code> becomes <code>%(key)</code>.<p>
200: *
201: * @param input the input to format as a macro
202: *
203: * @return the input formatted as a macro
204: */
205: public static String formatMacro(String input) {
206:
207: StringBuffer result = new StringBuffer(input.length() + 4);
208: result.append(I_CmsMacroResolver.MACRO_DELIMITER);
209: result.append(I_CmsMacroResolver.MACRO_START);
210: result.append(input);
211: result.append(I_CmsMacroResolver.MACRO_END);
212: return result.toString();
213: }
214:
215: /**
216: * Returns <code>true</code> if the given input String if formatted like a macro,
217: * that is it starts with <code>{@link I_CmsMacroResolver#MACRO_DELIMITER_OLD} +
218: * {@link I_CmsMacroResolver#MACRO_START_OLD}</code> and ends with
219: * <code>{@link I_CmsMacroResolver#MACRO_END_OLD}</code>.<p>
220: *
221: * @param input the input to check for a macro
222: * @return <code>true</code> if the given input String if formatted like a macro
223: */
224: public static boolean isMacro(String input) {
225:
226: if (CmsStringUtil.isEmpty(input) || (input.length() < 3)) {
227: return false;
228: }
229:
230: return (((input.charAt(0) == I_CmsMacroResolver.MACRO_DELIMITER_OLD) && ((input
231: .charAt(1) == I_CmsMacroResolver.MACRO_START_OLD) && (input
232: .charAt(input.length() - 1) == I_CmsMacroResolver.MACRO_END_OLD))) || ((input
233: .charAt(0) == I_CmsMacroResolver.MACRO_DELIMITER) && ((input
234: .charAt(1) == I_CmsMacroResolver.MACRO_START) && (input
235: .charAt(input.length() - 1) == I_CmsMacroResolver.MACRO_END))));
236: }
237:
238: /**
239: * Returns <code>true</code> if the given input String is a macro equal to the given macro name.<p>
240: *
241: * @param input the input to check for a macro
242: * @param macroName the macro name to check for
243: *
244: * @return <code>true</code> if the given input String is a macro equal to the given macro name
245: */
246: public static boolean isMacro(String input, String macroName) {
247:
248: if (isMacro(input)) {
249: return input.substring(2, input.length() - 1).equals(
250: macroName);
251: }
252: return false;
253: }
254:
255: /**
256: * Returns a macro for the given localization key with the given parameters.<p>
257: *
258: * @param keyName the name of the localized key
259: * @param params the optional parameter array
260: *
261: * @return a macro for the given localization key with the given parameters
262: */
263: public static String localizedKeyMacro(String keyName,
264: Object[] params) {
265:
266: String parameters = "";
267: if ((params != null) && (params.length > 0)) {
268: for (int i = 0; i < params.length; i++) {
269: if (params[i] != null) {
270: parameters += "|" + params[i].toString();
271: }
272: }
273: }
274: return "" + I_CmsMacroResolver.MACRO_DELIMITER
275: + I_CmsMacroResolver.MACRO_START
276: + CmsMacroResolver.KEY_LOCALIZED_PREFIX + keyName
277: + parameters + I_CmsMacroResolver.MACRO_END;
278: }
279:
280: /**
281: * Factory method to create a new {@link CmsMacroResolver} instance.<p>
282: *
283: * @return a new instance of a {@link CmsMacroResolver}
284: */
285: public static CmsMacroResolver newInstance() {
286:
287: return new CmsMacroResolver();
288: }
289:
290: /**
291: * Resolves the macros in the given input using the provided parameters.<p>
292: *
293: * A macro in the form <code>%(key)</code> or <code>${key}</code> in the content is replaced with it's assigned value
294: * returned by the <code>{@link I_CmsMacroResolver#getMacroValue(String)}</code> method of the given
295: * <code>{@link I_CmsMacroResolver}</code> instance.<p>
296: *
297: * If a macro is found that can not be mapped to a value by the given macro resolver,
298: * it is left untouched in the input.<p>
299: *
300: * @param input the input in which to resolve the macros
301: * @param cms the OpenCms user context to use when resolving macros
302: * @param messages the message resource bundle to use when resolving macros
303: *
304: * @return the input with the macros resolved
305: */
306: public static String resolveMacros(String input, CmsObject cms,
307: CmsMessages messages) {
308:
309: CmsMacroResolver resolver = new CmsMacroResolver();
310: resolver.m_cms = cms;
311: resolver.m_messages = messages;
312: resolver.m_keepEmptyMacros = true;
313: return resolver.resolveMacros(input);
314: }
315:
316: /**
317: * Resolves macros in the provided input String using the given macro resolver.<p>
318: *
319: * A macro in the form <code>%(key)</code> or <code>${key}</code> in the content is replaced with it's assigned value
320: * returned by the <code>{@link I_CmsMacroResolver#getMacroValue(String)}</code> method of the given
321: * <code>{@link I_CmsMacroResolver}</code> instance.<p>
322: *
323: * If a macro is found that can not be mapped to a value by the given macro resolver,
324: * <code>{@link I_CmsMacroResolver#isKeepEmptyMacros()}</code> controls if the macro is replaced by
325: * an empty String, or is left untouched in the input.<p>
326: *
327: * @param input the input in which to resolve the macros
328: * @param resolver the macro resolver to use
329: *
330: * @return the input with all macros resolved
331: */
332: public static String resolveMacros(final String input,
333: I_CmsMacroResolver resolver) {
334:
335: if ((input == null) || (input.length() < 3)) {
336: // macro must have at last 3 chars "${}" or "%()"
337: return input;
338: }
339:
340: int pn = input.indexOf(I_CmsMacroResolver.MACRO_DELIMITER);
341: int po = input.indexOf(I_CmsMacroResolver.MACRO_DELIMITER_OLD);
342:
343: if ((po == -1) && (pn == -1)) {
344: // no macro delimiter found in input
345: return input;
346: }
347:
348: int len = input.length();
349: StringBuffer result = new StringBuffer(len << 1);
350: int np, pp1, pp2, e;
351: String macro, value;
352: boolean keep = resolver.isKeepEmptyMacros();
353: boolean resolvedNone = true;
354: char ds, de;
355: int p;
356:
357: if ((po == -1) || ((pn > -1) && (pn < po))) {
358: p = pn;
359: ds = I_CmsMacroResolver.MACRO_START;
360: de = I_CmsMacroResolver.MACRO_END;
361: } else {
362: p = po;
363: ds = I_CmsMacroResolver.MACRO_START_OLD;
364: de = I_CmsMacroResolver.MACRO_END_OLD;
365: }
366:
367: // append chars before the first delimiter found
368: result.append(input.substring(0, p));
369: do {
370: pp1 = p + 1;
371: pp2 = pp1 + 1;
372: if (pp2 >= len) {
373: // remaining chars can't be a macro (minumum size is 3)
374: result.append(input.substring(p, len));
375: break;
376: }
377: // get the next macro delimiter
378: if ((pn > -1) && (pn < pp1)) {
379: pn = input.indexOf(I_CmsMacroResolver.MACRO_DELIMITER,
380: pp1);
381: }
382: if ((po > -1) && (po < pp1)) {
383: po = input.indexOf(
384: I_CmsMacroResolver.MACRO_DELIMITER_OLD, pp1);
385: }
386: if ((po == -1) && (pn == -1)) {
387: // none found, make sure remaining chars in this segement are appended
388: np = len;
389: } else {
390: // check if the next delimiter is old or new style
391: if ((po == -1) || ((pn > -1) && (pn < po))) {
392: np = pn;
393: } else {
394: np = po;
395: }
396: }
397: // check if the next char is a "macro start"
398: char st = input.charAt(pp1);
399: if (st == ds) {
400: // we have a starting macro sequence "${" or "%(", now check if this segment contains a "}" or ")"
401: e = input.indexOf(de, p);
402: if ((e > 0) && (e < np)) {
403: // this segment contains a closing macro delimiter "}" or "]", so we may have found a macro
404: macro = input.substring(pp2, e);
405: // resolve macro
406: value = resolver.getMacroValue(macro);
407: e++;
408: if (value != null) {
409: // macro was successfully resolved
410: result.append(value);
411: resolvedNone = false;
412: } else if (keep) {
413: // macro was unknown, but should be kept
414: result.append(input.substring(p, e));
415: }
416: } else {
417: // no complete macro "${...}" or "%(...)" in this segment
418: e = p;
419: }
420: } else {
421: // no macro start char after the "$" or "%"
422: e = p;
423: }
424: // set macro style for next delimiter found
425: if (np == pn) {
426: ds = I_CmsMacroResolver.MACRO_START;
427: de = I_CmsMacroResolver.MACRO_END;
428: } else {
429: ds = I_CmsMacroResolver.MACRO_START_OLD;
430: de = I_CmsMacroResolver.MACRO_END_OLD;
431: }
432: // append the remaining chars after the macro to the start of the next macro
433: result.append(input.substring(e, np));
434: // this is a nerdy joke ;-)
435: p = np;
436: } while (p < len);
437:
438: if (resolvedNone && keep) {
439: // nothing was resolved and macros should be kept, return original input
440: return input;
441: }
442:
443: // input was changed during resolving of macros
444: return result.toString();
445: }
446:
447: /**
448: * Strips the macro delimiters from the given input,
449: * for example <code>%(key)</code> or <code>${key}</code> becomes <code>key</code>.<p>
450: *
451: * In case the input is not a macro, <code>null</code> is returned.<p>
452: *
453: * @param input the input to strip
454: *
455: * @return the macro stripped from the input, or <code>null</code>
456: */
457: public static String stripMacro(String input) {
458:
459: if (isMacro(input)) {
460: return input.substring(2, input.length() - 1);
461: }
462: return null;
463: }
464:
465: /**
466: * Adds a customized macro to this macro resolver.<p>
467: *
468: * @param key the macro to add
469: * @param value the value to return if the macro is encountered
470: */
471: public void addMacro(String key, String value) {
472:
473: if (m_additionalMacros == null) {
474: // use lazy initializing
475: m_additionalMacros = new HashMap();
476: }
477: m_additionalMacros.put(key, value);
478: }
479:
480: /**
481: * @see org.opencms.util.I_CmsMacroResolver#getMacroValue(java.lang.String)
482: */
483: public String getMacroValue(String macro) {
484:
485: if (m_messages != null) {
486: if (macro.startsWith(CmsMacroResolver.KEY_LOCALIZED_PREFIX)) {
487: String keyName = macro
488: .substring(CmsMacroResolver.KEY_LOCALIZED_PREFIX
489: .length());
490: return m_messages.keyWithParams(keyName);
491: }
492: }
493:
494: if (m_jspPageContext != null) {
495:
496: if (m_jspPageContext.getRequest() != null) {
497: if (macro
498: .startsWith(CmsMacroResolver.KEY_REQUEST_PARAM)) {
499: // the key is a request parameter
500: macro = macro
501: .substring(CmsMacroResolver.KEY_REQUEST_PARAM
502: .length());
503: String result = m_jspPageContext.getRequest()
504: .getParameter(macro);
505: if ((result == null)
506: && macro.equals(KEY_PROJECT_ID)) {
507: result = m_cms.getRequestContext()
508: .currentProject().getUuid().toString();
509: }
510: return result;
511: }
512:
513: if ((m_cms != null)
514: && macro
515: .startsWith(CmsMacroResolver.KEY_PROPERTY_ELEMENT)) {
516:
517: // the key is a cms property to be read on the current element
518:
519: macro = macro
520: .substring(CmsMacroResolver.KEY_PROPERTY_ELEMENT
521: .length());
522: CmsFlexController controller = CmsFlexController
523: .getController(m_jspPageContext
524: .getRequest());
525: try {
526: CmsProperty property = m_cms
527: .readPropertyObject(controller
528: .getCurrentRequest()
529: .getElementUri(), macro, false);
530: if (property != CmsProperty.getNullProperty()) {
531: return property.getValue();
532: }
533: } catch (CmsException e) {
534: if (LOG.isWarnEnabled()) {
535: LOG
536: .warn(
537: Messages
538: .get()
539: .getBundle()
540: .key(
541: Messages.LOG_PROPERTY_READING_FAILED_2,
542: macro,
543: controller
544: .getCurrentRequest()
545: .getElementUri()),
546: e);
547: }
548: }
549: }
550: }
551:
552: if (macro.startsWith(CmsMacroResolver.KEY_PAGE_CONTEXT)) {
553: // the key is a page context object
554: macro = macro
555: .substring(CmsMacroResolver.KEY_PAGE_CONTEXT
556: .length());
557: int scope = m_jspPageContext.getAttributesScope(macro);
558: return m_jspPageContext.getAttribute(macro, scope)
559: .toString();
560: }
561: }
562:
563: if (m_cms != null) {
564:
565: if (macro.startsWith(CmsMacroResolver.KEY_PROPERTY)) {
566: // the key is a cms property to be read on the current request URI
567: macro = macro.substring(CmsMacroResolver.KEY_PROPERTY
568: .length());
569: try {
570: CmsProperty property = m_cms.readPropertyObject(
571: m_cms.getRequestContext().getUri(), macro,
572: true);
573: if (property != CmsProperty.getNullProperty()) {
574: return property.getValue();
575: }
576: } catch (CmsException e) {
577: if (LOG.isWarnEnabled()) {
578: CmsMessageContainer message = Messages
579: .get()
580: .container(
581: Messages.LOG_PROPERTY_READING_FAILED_2,
582: macro,
583: m_cms.getRequestContext()
584: .getUri());
585: LOG.warn(message.key(), e);
586: }
587: }
588: return null;
589: }
590:
591: if (macro.startsWith(CmsMacroResolver.KEY_ATTRIBUTE)) {
592: // the key is an OpenCms runtime attribute
593: macro = macro.substring(CmsMacroResolver.KEY_ATTRIBUTE
594: .length());
595: Object attribute = m_cms.getRequestContext()
596: .getAttribute(macro);
597: if (attribute != null) {
598: return attribute.toString();
599: }
600: return null;
601: }
602:
603: if (macro.startsWith(CmsMacroResolver.KEY_OPENCMS)) {
604:
605: // the key is a shortcut for a cms runtime value
606:
607: String originalKey = macro;
608: macro = macro.substring(CmsMacroResolver.KEY_OPENCMS
609: .length());
610: int index = VALUE_NAMES.indexOf(macro);
611: String value = null;
612:
613: switch (index) {
614: case 0:
615: // "uri"
616: value = m_cms.getRequestContext().getUri();
617: break;
618: case 1:
619: // "filename"
620: value = m_resourceName;
621: break;
622: case 2:
623: // folder
624: value = m_cms.getRequestContext().getFolderUri();
625: break;
626: case 3:
627: // default.encoding
628: value = OpenCms.getSystemInfo()
629: .getDefaultEncoding();
630: break;
631: case 4:
632: // remoteaddress
633: value = m_cms.getRequestContext()
634: .getRemoteAddress();
635: break;
636: case 5:
637: // webapp
638: value = OpenCms.getSystemInfo()
639: .getWebApplicationName();
640: break;
641: case 6:
642: // webbasepath
643: value = OpenCms.getSystemInfo()
644: .getWebApplicationRfsPath();
645: break;
646: case 7:
647: // version
648: value = OpenCms.getSystemInfo().getVersionNumber();
649: break;
650: default:
651: // return the key "as is"
652: value = originalKey;
653: break;
654: }
655:
656: return value;
657: }
658:
659: if (CmsMacroResolver.KEY_CURRENT_USER_NAME.equals(macro)) {
660: // the key is the current users login name
661: return m_cms.getRequestContext().currentUser()
662: .getName();
663: }
664:
665: if (CmsMacroResolver.KEY_CURRENT_USER_FIRSTNAME
666: .equals(macro)) {
667: // the key is the current users first name
668: return m_cms.getRequestContext().currentUser()
669: .getFirstname();
670: }
671:
672: if (CmsMacroResolver.KEY_CURRENT_USER_LASTNAME
673: .equals(macro)) {
674: // the key is the current users last name
675: return m_cms.getRequestContext().currentUser()
676: .getLastname();
677: }
678:
679: if (CmsMacroResolver.KEY_CURRENT_USER_DISPLAYNAME
680: .equals(macro)) {
681: // the key is the current users display name
682: try {
683: if (m_messages != null) {
684: return m_cms.getRequestContext().currentUser()
685: .getDisplayName(m_cms,
686: m_messages.getLocale());
687: } else {
688: return m_cms.getRequestContext().currentUser()
689: .getDisplayName(
690: m_cms,
691: m_cms.getRequestContext()
692: .getLocale());
693: }
694: } catch (CmsException e) {
695: // ignore, macro can not be resolved
696: }
697: }
698:
699: if (CmsMacroResolver.KEY_CURRENT_ORGUNIT_FQN.equals(macro)) {
700: // the key is the current organizational unit fully qualified name
701: return m_cms.getRequestContext().getOuFqn();
702: }
703:
704: if (CmsMacroResolver.KEY_CURRENT_ORGUNIT_DESCRIPTION
705: .equals(macro)) {
706: // the key is the current organizational unit description
707: try {
708: CmsOrganizationalUnit ou = OpenCms
709: .getOrgUnitManager()
710: .readOrganizationalUnit(
711: m_cms,
712: m_cms.getRequestContext()
713: .getOuFqn());
714: if (m_messages != null) {
715: return ou
716: .getDescription(m_messages.getLocale());
717: } else {
718: return ou.getDescription(m_cms
719: .getRequestContext().getLocale());
720: }
721: } catch (CmsException e) {
722: // ignore, macro can not be resolved
723: }
724: }
725:
726: if (CmsMacroResolver.KEY_CURRENT_USER_FULLNAME
727: .equals(macro)) {
728: // the key is the current users full name
729: return m_cms.getRequestContext().currentUser()
730: .getFullName();
731: }
732:
733: if (CmsMacroResolver.KEY_CURRENT_USER_EMAIL.equals(macro)) {
734: // the key is the current users email address
735: return m_cms.getRequestContext().currentUser()
736: .getEmail();
737: }
738:
739: if (CmsMacroResolver.KEY_CURRENT_USER_STREET.equals(macro)) {
740: // the key is the current users address
741: return m_cms.getRequestContext().currentUser()
742: .getAddress();
743: }
744:
745: if (CmsMacroResolver.KEY_CURRENT_USER_ZIP.equals(macro)) {
746: // the key is the current users zip code
747: return m_cms.getRequestContext().currentUser()
748: .getZipcode();
749: }
750:
751: if (CmsMacroResolver.KEY_CURRENT_USER_COUNTRY.equals(macro)) {
752: // the key is the current users country
753: return m_cms.getRequestContext().currentUser()
754: .getCountry();
755: }
756:
757: if (CmsMacroResolver.KEY_CURRENT_USER_CITY.equals(macro)) {
758: // the key is the current users city
759: return m_cms.getRequestContext().currentUser()
760: .getCity();
761: }
762:
763: if (CmsMacroResolver.KEY_CURRENT_USER_LASTLOGIN
764: .equals(macro)
765: && (m_messages != null)) {
766: // the key is the current users last login timestamp
767: return m_messages.getDateTime(m_cms.getRequestContext()
768: .currentUser().getLastlogin());
769: }
770:
771: if (CmsMacroResolver.KEY_REQUEST_URI.equals(macro)) {
772: // the key is the currently requested uri
773: return m_cms.getRequestContext().getUri();
774: }
775:
776: if (CmsMacroResolver.KEY_REQUEST_FOLDER.equals(macro)) {
777: // the key is the currently requested folder
778: return CmsResource.getParentFolder(m_cms
779: .getRequestContext().getUri());
780: }
781:
782: if (CmsMacroResolver.KEY_REQUEST_ENCODING.equals(macro)) {
783: // the key is the current encoding of the request
784: return m_cms.getRequestContext().getEncoding();
785: }
786:
787: if (CmsMacroResolver.KEY_REQUEST_LOCALE.equals(macro)) {
788: // the key is the current locale of the request
789: return m_cms.getRequestContext().getLocale().toString();
790: }
791:
792: }
793:
794: if (CmsMacroResolver.KEY_CURRENT_TIME.equals(macro)) {
795: // the key is the current system time
796: return String.valueOf(System.currentTimeMillis());
797: }
798:
799: if (m_additionalMacros != null) {
800: return (String) m_additionalMacros.get(macro);
801: }
802:
803: return null;
804: }
805:
806: /**
807: * @see org.opencms.util.I_CmsMacroResolver#isKeepEmptyMacros()
808: */
809: public boolean isKeepEmptyMacros() {
810:
811: return m_keepEmptyMacros;
812: }
813:
814: /**
815: * Resolves the macros in the given input.<p>
816: *
817: * Calls <code>{@link #resolveMacros(String)}</code> until no more macros can
818: * be resolved in the input. This way "nested" macros in the input are resolved as well.<p>
819: *
820: * @see org.opencms.util.I_CmsMacroResolver#resolveMacros(java.lang.String)
821: */
822: public String resolveMacros(String input) {
823:
824: String result = input;
825:
826: if (input != null) {
827: String lastResult;
828: do {
829: // save result for next comparison
830: lastResult = result;
831: // resolve the macros
832: result = CmsMacroResolver.resolveMacros(result, this );
833: // if nothing changes then the final result is found
834: } while (!result.equals(lastResult));
835: }
836:
837: // return the result
838: return result;
839: }
840:
841: /**
842: * Provides a set of additional macros to this macro resolver.<p>
843: *
844: * Macros added with {@link #addMacro(String, String)} are added to the same set
845: *
846: * @param additionalMacros the additional macros to add
847: *
848: * @return this instance of the macro resolver
849: */
850: public CmsMacroResolver setAdditionalMacros(Map additionalMacros) {
851:
852: m_additionalMacros = additionalMacros;
853: return this ;
854: }
855:
856: /**
857: * Provides an OpenCms user context to this macro resolver, required to resolve certain macros.<p>
858: *
859: * @param cms the OpenCms user context
860: *
861: * @return this instance of the macro resolver
862: */
863: public CmsMacroResolver setCmsObject(CmsObject cms) {
864:
865: m_cms = cms;
866: return this ;
867: }
868:
869: /**
870: * Provides a JSP page context to this macro resolver, required to resolve certain macros.<p>
871: *
872: * @param jspPageContext the JSP page context to use
873: *
874: * @return this instance of the macro resolver
875: */
876: public CmsMacroResolver setJspPageContext(PageContext jspPageContext) {
877:
878: m_jspPageContext = jspPageContext;
879: return this ;
880: }
881:
882: /**
883: * Controls of macros that can't be resolved are left unchanged in the input,
884: * or are replaced with an empty String.<p>
885: *
886: * @param keepEmptyMacros the replacement flag to use
887: *
888: * @return this instance of the macro resolver
889: *
890: * @see #isKeepEmptyMacros()
891: */
892: public CmsMacroResolver setKeepEmptyMacros(boolean keepEmptyMacros) {
893:
894: m_keepEmptyMacros = keepEmptyMacros;
895: return this ;
896: }
897:
898: /**
899: * Provides a set of <code>{@link CmsMessages}</code> to this macro resolver,
900: * required to resolve localized macros.<p>
901: *
902: * @param messages the message resource bundle to use
903: *
904: * @return this instance of the macro resolver
905: */
906: public CmsMacroResolver setMessages(CmsMessages messages) {
907:
908: m_messages = messages;
909: return this ;
910: }
911:
912: /**
913: * Provides a resource name to this macro resolver, required to resolve certain macros.<p>
914: *
915: * @param resourceName the resource name to use
916: *
917: * @return this instance of the macro resolver
918: */
919: public CmsMacroResolver setResourceName(String resourceName) {
920:
921: m_resourceName = resourceName;
922: return this;
923: }
924: }
|