KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > jpivot > table > span > PropertyUtils


1 /*
2  * ====================================================================
3  * This software is subject to the terms of the Common Public License
4  * Agreement, available at the following URL:
5  * http://www.opensource.org/licenses/cpl.html .
6  * Copyright (C) 2003-2004 TONBELLER AG.
7  * All Rights Reserved.
8  * You must accept the terms of that agreement to use this software.
9  * ====================================================================
10  *
11  *
12  */

13 package com.tonbeller.jpivot.table.span;
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.Collections JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.HashSet JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Set JavaDoc;
23 import java.util.StringTokenizer JavaDoc;
24
25 import org.w3c.dom.Element JavaDoc;
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 /**
33  * Handles nested Properties.
34  * <p>
35  * Example 1:
36  * <code>src="x", HREF="y"</code> becomes
37  * <pre>
38  * &lt;property name="src" value="x"/&gt;
39  * &lt;property name="href" value="y"/&gt;
40  * </pre>
41  * <p>
42  * Example 2:
43  * <code>image="x", image.src="y", image.href="z"</code> becomes
44  * <pre>
45  * &lt;property name="image" value="x&gt;
46  * &lt;property name="src" value="y"/&gt;
47  * &lt;property name="href" value="z"/&gt;
48  * &lt;/property&gt;
49  * </pre>
50  */

51 public class PropertyUtils {
52
53   private static final String JavaDoc delimiter = ".";
54   private static final char delimiterChar = '.';
55   private static final String JavaDoc INLINE_PREFIX = "inline.property.";
56   
57   public static final String JavaDoc STYLE_PROPERTY = "style";
58
59   /**
60    * maps multiple names in lower case to the 'standard' name of the inline property. Example:
61    * 'image' and 'bild' (german) map to the standard property name 'image'.
62    */

63   static Map JavaDoc inlineProps;
64
65   static {
66     Map JavaDoc map = new HashMap JavaDoc();
67     int prefixLength = INLINE_PREFIX.length();
68     Resources res = Resources.instance(PropertyUtils.class);
69     for (Iterator JavaDoc it = res.keySet().iterator(); it.hasNext();) {
70       String JavaDoc key = (String JavaDoc) it.next();
71       if (key.startsWith(INLINE_PREFIX)) {
72         String JavaDoc 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   /**
84    * true if name contains the delimiter '.'
85    */

86   public static boolean isNested(String JavaDoc propertyName) {
87     return propertyName.indexOf(delimiterChar) > 0;
88   }
89
90   /**
91    * if propertyName denotes a nested property (i.e. contains the '.' delimiter),
92    * returns the name of the root property.
93    * @param propertyName name of nested Property, e.g. "myName.image"
94    * @return name of root property, e.g. "myName"
95    */

96   public static String JavaDoc getRootName(String JavaDoc propertyName) {
97     int pos = propertyName.indexOf(delimiterChar);
98     if (pos >= 0)
99       return propertyName.substring(0, pos);
100     return propertyName;
101   }
102
103   /**
104    * true if name is rendered inline (e.g. 'link', 'color', 'arrow')
105    */

106   public static boolean isInline(String JavaDoc propertyName) {
107     if (propertyName.startsWith("$"))
108       return true;
109     String JavaDoc name = propertyName.toLowerCase();
110     return inlineProps.containsKey(name);
111   }
112   
113   public static boolean isStyleProperty(String JavaDoc propertyName) {
114     String JavaDoc name = propertyName.toLowerCase();
115     String JavaDoc value = (String JavaDoc)inlineProps.get(name);
116     return STYLE_PROPERTY.equals(value);
117   }
118
119   /**
120    * creates nested properties where the hierarchy is derived by the
121    * property names.
122    */

123   public static Property[] normalize(Property[] properties) {
124     if (!needsNormalization(properties))
125       return properties;
126     Map JavaDoc map = new HashMap JavaDoc();
127     List JavaDoc result = new ArrayList JavaDoc();
128     for (int i = 0; i < properties.length; i++) {
129       Property src = properties[i];
130       PropertyImpl parent = null;
131       StringBuffer JavaDoc nameBuffer = new StringBuffer JavaDoc();
132       StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(src.getName(), delimiter);
133       while (st.hasMoreTokens()) {
134         String JavaDoc token = st.nextToken();
135         nameBuffer.append(delimiterChar).append(token);
136         String JavaDoc 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   /**
173    * adds property children to the target element. If the
174    * name of a property contains the "." char, its treated specially (see below).
175    */

176
177   public static void addProperties(Element JavaDoc target, Property[] properties) {
178     properties = normalize(properties);
179     recurseAddProperties(target, properties, false);
180   }
181
182   /**
183    * adds inline properties to <code>caption</code> and converts
184    * the property names to lower case.
185    */

186   public static void addInlineProperties(Element JavaDoc target, Property[] properties) {
187     if (properties.length > 0) {
188       List JavaDoc list = new ArrayList JavaDoc();
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 JavaDoc 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 JavaDoc elem = parent.getOwnerDocument().createElement("property");
205       parent.appendChild(elem);
206       if (inline) {
207         String JavaDoc name = p.getName().toLowerCase();
208         name = (String JavaDoc) 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   /**
219    * removes Metas that correspond to nested properties
220    * @param metas
221    * @return
222    */

223   public static MemberPropertyMeta[] getRootMetas(MemberPropertyMeta[] metas) {
224     Set JavaDoc nameSet = new HashSet JavaDoc();
225     List JavaDoc roots = new ArrayList JavaDoc();
226     // copy root properties
227
for (int i = 0; i < metas.length; i++) {
228       String JavaDoc name = metas[i].getName();
229       if (!isNested(name)) {
230         nameSet.add(name);
231         roots.add(metas[i]);
232       }
233     }
234
235     // create a root property for nested properties
236
// that do not have a root property
237
for (int i = 0; i < metas.length; i++) {
238       String JavaDoc name = metas[i].getName();
239       if (isNested(name)) {
240         String JavaDoc rootName = getRootName(name);
241         if (!nameSet.contains(rootName)) {
242           nameSet.add(rootName);
243           // often label == propertyName, so better cut off '.'
244
String JavaDoc label = getRootName(metas[i].getLabel());
245           String JavaDoc 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   /**
254    * returns the Inline Property with given name
255    * @param props all properties
256    * @param name one of the names of the inline property
257    * @return null or the property
258    */

259   public static Property getInlineProperty(Property[] props, String JavaDoc name) {
260     name = (String JavaDoc) inlineProps.get(name.toLowerCase());
261     for (int i = 0; i < props.length; i++) {
262       String JavaDoc s = props[i].getName().toLowerCase();
263       s = (String JavaDoc) inlineProps.get(s);
264       if (s != null && s.equals(name))
265         return props[i];
266     }
267     return null;
268   }
269
270 }
271
Popular Tags