1 13 package com.tonbeller.jpivot.table.span; 14 15 import java.util.ArrayList ; 16 import java.util.Collections ; 17 import java.util.HashMap ; 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 import java.util.Set ; 23 import java.util.StringTokenizer ; 24 25 import org.w3c.dom.Element ; 26 27 import com.tonbeller.jpivot.olap.model.MemberPropertyMeta; 28 import com.tonbeller.jpivot.olap.model.Property; 29 import com.tonbeller.jpivot.olap.model.impl.PropertyImpl; 30 import com.tonbeller.tbutils.res.Resources; 31 32 51 public class PropertyUtils { 52 53 private static final String delimiter = "."; 54 private static final char delimiterChar = '.'; 55 private static final String INLINE_PREFIX = "inline.property."; 56 57 public static final String STYLE_PROPERTY = "style"; 58 59 63 static Map inlineProps; 64 65 static { 66 Map map = new HashMap (); 67 int prefixLength = INLINE_PREFIX.length(); 68 Resources res = Resources.instance(PropertyUtils.class); 69 for (Iterator it = res.keySet().iterator(); it.hasNext();) { 70 String key = (String ) it.next(); 71 if (key.startsWith(INLINE_PREFIX)) { 72 String value = res.getString(key); 73 key = key.substring(prefixLength); 74 map.put(key, value); 75 } 76 } 77 inlineProps = Collections.unmodifiableMap(map); 78 }; 79 80 private PropertyUtils() { 81 } 82 83 86 public static boolean isNested(String propertyName) { 87 return propertyName.indexOf(delimiterChar) > 0; 88 } 89 90 96 public static String getRootName(String propertyName) { 97 int pos = propertyName.indexOf(delimiterChar); 98 if (pos >= 0) 99 return propertyName.substring(0, pos); 100 return propertyName; 101 } 102 103 106 public static boolean isInline(String propertyName) { 107 if (propertyName.startsWith("$")) 108 return true; 109 String name = propertyName.toLowerCase(); 110 return inlineProps.containsKey(name); 111 } 112 113 public static boolean isStyleProperty(String propertyName) { 114 String name = propertyName.toLowerCase(); 115 String value = (String )inlineProps.get(name); 116 return STYLE_PROPERTY.equals(value); 117 } 118 119 123 public static Property[] normalize(Property[] properties) { 124 if (!needsNormalization(properties)) 125 return properties; 126 Map map = new HashMap (); 127 List result = new ArrayList (); 128 for (int i = 0; i < properties.length; i++) { 129 Property src = properties[i]; 130 PropertyImpl parent = null; 131 StringBuffer nameBuffer = new StringBuffer (); 132 StringTokenizer st = new StringTokenizer (src.getName(), delimiter); 133 while (st.hasMoreTokens()) { 134 String token = st.nextToken(); 135 nameBuffer.append(delimiterChar).append(token); 136 String name = nameBuffer.toString(); 137 138 PropertyImpl child = (PropertyImpl) map.get(name); 139 if (child == null) { 140 child = new PropertyImpl(); 141 child.setName(token); 142 child.setLabel(token); 143 child.setValue(""); 144 map.put(name, child); 145 if (parent == null) 146 result.add(child); 147 else 148 parent.addProperty(child); 149 } 150 parent = child; 151 } 152 parent.setValue(src.getValue()); 153 parent.setLabel(src.getLabel()); 154 parent.setAlignment(src.getAlignment()); 155 } 156 return (Property[]) result.toArray(new Property[result.size()]); 157 } 158 159 private static boolean needsNormalization(Property[] properties) { 160 if (properties == null || properties.length < 2) 161 return false; 162 for (int i = 0; i < properties.length; i++) { 163 Property p = properties[i]; 164 if (!p.isNormalizable()) 165 continue; 166 if (p.getName().indexOf(delimiter) > 0) 167 return true; 168 } 169 return false; 170 } 171 172 176 177 public static void addProperties(Element target, Property[] properties) { 178 properties = normalize(properties); 179 recurseAddProperties(target, properties, false); 180 } 181 182 186 public static void addInlineProperties(Element target, Property[] properties) { 187 if (properties.length > 0) { 188 List list = new ArrayList (); 189 for (int i = 0; i < properties.length; i++) { 190 if (isInline(properties[i].getName())) 191 list.add(properties[i]); 192 } 193 properties = (Property[]) list.toArray(new Property[list.size()]); 194 properties = normalize(properties); 195 recurseAddProperties(target, properties, true); 196 } 197 } 198 199 private static void recurseAddProperties(Element parent, Property[] properties, boolean inline) { 200 if (properties == null) 201 return; 202 for (int i = 0; i < properties.length; i++) { 203 Property p = properties[i]; 204 Element elem = parent.getOwnerDocument().createElement("property"); 205 parent.appendChild(elem); 206 if (inline) { 207 String name = p.getName().toLowerCase(); 208 name = (String ) inlineProps.get(name); 209 elem.setAttribute("name", name); 210 } else 211 elem.setAttribute("name", p.getName()); 212 elem.setAttribute("label", p.getLabel()); 213 elem.setAttribute("value", p.getValue()); 214 recurseAddProperties(elem, p.getProperties(), inline); 215 } 216 } 217 218 223 public static MemberPropertyMeta[] getRootMetas(MemberPropertyMeta[] metas) { 224 Set nameSet = new HashSet (); 225 List roots = new ArrayList (); 226 for (int i = 0; i < metas.length; i++) { 228 String name = metas[i].getName(); 229 if (!isNested(name)) { 230 nameSet.add(name); 231 roots.add(metas[i]); 232 } 233 } 234 235 for (int i = 0; i < metas.length; i++) { 238 String name = metas[i].getName(); 239 if (isNested(name)) { 240 String rootName = getRootName(name); 241 if (!nameSet.contains(rootName)) { 242 nameSet.add(rootName); 243 String label = getRootName(metas[i].getLabel()); 245 String scope = metas[i].getScope(); 246 roots.add(new MemberPropertyMeta(label, rootName, scope)); 247 } 248 } 249 } 250 return (MemberPropertyMeta[]) roots.toArray(new MemberPropertyMeta[roots.size()]); 251 } 252 253 259 public static Property getInlineProperty(Property[] props, String name) { 260 name = (String ) inlineProps.get(name.toLowerCase()); 261 for (int i = 0; i < props.length; i++) { 262 String s = props[i].getName().toLowerCase(); 263 s = (String ) inlineProps.get(s); 264 if (s != null && s.equals(name)) 265 return props[i]; 266 } 267 return null; 268 } 269 270 } 271 | Popular Tags |