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 }