001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.hivemind.schema.rules;
016
017 import java.util.Collections;
018 import java.util.HashMap;
019 import java.util.Map;
020
021 import org.apache.commons.logging.Log;
022 import org.apache.commons.logging.LogFactory;
023 import org.apache.hivemind.ApplicationRuntimeException;
024 import org.apache.hivemind.Element;
025 import org.apache.hivemind.ErrorHandler;
026 import org.apache.hivemind.HiveMind;
027 import org.apache.hivemind.internal.Module;
028 import org.apache.hivemind.schema.SchemaProcessor;
029 import org.apache.hivemind.schema.Translator;
030 import org.apache.hivemind.util.PropertyUtils;
031
032 /**
033 * Static methods useful to {@link org.apache.hivemind.schema.Rule}s and
034 * {@link org.apache.hivemind.schema.Translator}s.
035 *
036 * @author Howard Lewis Ship
037 */
038 public class RuleUtils
039 {
040 private static final Log LOG = LogFactory.getLog(RuleUtils.class);
041
042 /**
043 * Used to convert a {@link org.apache.hivemind.schema.Translator} initializer string of the
044 * form: <code><i>key</i>=<i>value</i>[,<i>key</i>=<i>value<i>]*</code> into a Map of
045 * keys and values. The keys and values are Strings.
046 */
047 public static Map convertInitializer(String initializer)
048 {
049 if (HiveMind.isBlank(initializer))
050 return Collections.EMPTY_MAP;
051
052 Map result = new HashMap();
053
054 int lastCommax = -1;
055 int inputLength = initializer.length();
056
057 while (lastCommax < inputLength)
058 {
059 int nextCommax = initializer.indexOf(',', lastCommax + 1);
060
061 if (nextCommax < 0)
062 nextCommax = inputLength;
063
064 String term = initializer.substring(lastCommax + 1, nextCommax);
065
066 int equalsx = term.indexOf('=');
067
068 if (equalsx <= 0)
069 throw new ApplicationRuntimeException(RulesMessages.invalidInitializer(initializer));
070
071 String key = term.substring(0, equalsx);
072 String value = term.substring(equalsx + 1);
073
074 result.put(key, value);
075
076 lastCommax = nextCommax;
077 }
078
079 return result;
080 }
081
082 /**
083 * Invoked to process text from an attribute or from an element's content. Performs two jobs:
084 * <ul>
085 * <li>Convert localized message references to localized strings
086 * <li>Expand symbols using
087 * {@link org.apache.hivemind.Registry#expandSymbols(String, Location)}
088 * </ul>
089 * <p>
090 * Note: if the input is a localized message then no symbol expansion takes place. Localized
091 * message references are simply strings that begin with '%'. The remainder of the string is the
092 * message key.
093 * <p>
094 * A null input value passes through unchanged.
095 */
096 public static String processText(SchemaProcessor processor, Element element, String inputValue)
097 {
098 if (inputValue == null)
099 return null;
100
101 Module contributingModule = processor.getContributingModule();
102
103 if (inputValue.startsWith("%"))
104 {
105 String key = inputValue.substring(1);
106
107 return contributingModule.getMessages().getMessage(key);
108 }
109
110 return contributingModule.expandSymbols(inputValue, element.getLocation());
111 }
112
113 /**
114 * Sets a property of the target object to the given value. Logs an error if there is a problem.
115 */
116 public static void setProperty(SchemaProcessor processor, Element element, String propertyName,
117 Object target, Object value)
118 {
119 try
120 {
121 PropertyUtils.write(target, propertyName, value);
122 }
123 catch (Exception ex)
124 {
125 // Have to decide if we need to display the location of the rule
126 // or the element.
127
128 ErrorHandler errorHandler = processor.getContributingModule().getErrorHandler();
129 errorHandler.error(LOG, RulesMessages.unableToSetElementProperty(
130 propertyName,
131 target,
132 processor,
133 element,
134 ex), element.getLocation(), ex);
135 }
136 }
137
138 /**
139 * Convienience for invoking {@link Module#getTranslator(String)}.
140 *
141 * @param processor
142 * the processor for the schema being converted
143 * @param translator
144 * the string identifying the translator to provide (may be null)
145 * @return a translator obtained via the contributing module, or an instance of
146 * {@link NullTranslator}
147 */
148 public static Translator getTranslator(SchemaProcessor processor, String translator)
149 {
150 if (translator == null)
151 return new NullTranslator();
152
153 return processor.getContributingModule().getTranslator(translator);
154 }
155 }