KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > metadata > parser > JdoExtension


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.metadata.parser;
13
14 import com.versant.core.common.Debug;
15 import com.versant.core.util.BeanUtils;
16 import com.versant.core.util.IntObjectHashMap;
17
18 import java.io.PrintStream JavaDoc;
19 import java.lang.reflect.Field JavaDoc;
20 import java.util.*;
21
22 import com.versant.core.common.BindingSupportImpl;
23
24 /**
25  * This is one of our vendor extensions with the key string converted to
26  * an int constant for easy processing.
27  */

28 public final class JdoExtension extends JdoElement implements JdoExtensionKeys {
29
30     /**
31      * This is the special value used to indicate that constraints, indexes
32      * and so on should not be generated.
33      */

34     public static final String JavaDoc NO_VALUE = "{no}";
35
36     public static final String JavaDoc NAME_VALUE = "{name}";
37     public static final String JavaDoc FULLNAME_VALUE = "{fullname}";
38     public static final String JavaDoc HASH_VALUE = "{hash}";
39
40     public int key;
41     public String JavaDoc value;
42     public JdoExtension[] nested;
43     public JdoElement parent;
44
45     private static final Map STR_KEY_MAP = new HashMap();
46     private static final IntObjectHashMap KEY_STR_MAP = new IntObjectHashMap();
47     private static final HashMap PRIMITIVE_TYPE_MAP = new HashMap(17);
48
49     static {
50         // find all the valid keys and add them to the maps
51
Field JavaDoc[] a = JdoExtensionKeys.class.getFields();
52         for (int i = a.length - 1; i >= 0; i--) {
53             Field JavaDoc f = a[i];
54             String JavaDoc key = f.getName().replace('_', '-').toLowerCase();
55
56             try {
57                 int v = f.getInt(null);
58                 STR_KEY_MAP.put(key, new Integer JavaDoc(v));
59                 KEY_STR_MAP.put(v, key);
60             } catch (IllegalAccessException JavaDoc e) {
61                 throw BindingSupportImpl.getInstance().internal(e.getMessage(), e);
62             }
63         }
64
65         // build map of primitive types
66
PRIMITIVE_TYPE_MAP.put("boolean", Boolean.TYPE);
67         PRIMITIVE_TYPE_MAP.put("byte", Byte.TYPE);
68         PRIMITIVE_TYPE_MAP.put("char", Character.TYPE);
69         PRIMITIVE_TYPE_MAP.put("short", Short.TYPE);
70         PRIMITIVE_TYPE_MAP.put("int", Integer.TYPE);
71         PRIMITIVE_TYPE_MAP.put("long", Long.TYPE);
72         PRIMITIVE_TYPE_MAP.put("float", Float.TYPE);
73         PRIMITIVE_TYPE_MAP.put("double", Double.TYPE);
74     }
75
76     public JdoExtension createCopy(JdoElement pe) {
77         JdoExtension copy = new JdoExtension();
78         copy.key = key;
79         copy.value = value;
80
81         if (nested != null) {
82             copy.nested = new JdoExtension[nested.length];
83             for (int i = 0; i < nested.length; i++) {
84                 JdoExtension jdoExtension = nested[i];
85                 copy.nested[i] = jdoExtension.createCopy(copy);
86             }
87         }
88         copy.parent = pe;
89         return copy;
90     }
91
92     public JdoElement getParent() {
93         return parent;
94     }
95
96     /**
97      * Get information for this element to be used in building up a
98      * context string.
99      *
100      * @see #getContext
101      */

102     public String JavaDoc getSubContext() {
103         if (value == null) return toKeyString(key);
104         return toKeyString(key) + "=\"" + value + '"';
105     }
106
107     /**
108      * Is this a common extension? This method must be kept in sync with the
109      * constants.
110      *
111      * @see JdoExtensionKeys
112      */

113     public boolean isCommon() {
114         return key < 100;
115     }
116
117     /**
118      * Is this a jdbc extension? This method must be kept in sync with the
119      * constants.
120      *
121      * @see JdoExtensionKeys
122      */

123     public boolean isJdbc() {
124         return key >= 100 && key <= 199;
125     }
126
127     /**
128      * Convert a String key value into an int constant.
129      *
130      * @return Key constant or Integer.MIN_VALUE if not valid
131      * @see JdoExtensionKeys
132      */

133     public static int parseKey(String JavaDoc key) {
134         Integer JavaDoc v = (Integer JavaDoc)STR_KEY_MAP.get(key);
135         return v == null ? Integer.MIN_VALUE : v.intValue();
136     }
137
138     /**
139      * Convert ant int key value into a String.
140      *
141      * @see JdoExtensionKeys
142      */

143     public static String JavaDoc toKeyString(int key) {
144         return (String JavaDoc)KEY_STR_MAP.get(key);
145     }
146
147     public String JavaDoc toString() {
148         return getSubContext();
149     }
150
151     public void dump() {
152         dump(Debug.OUT, "");
153     }
154
155     public void dump(PrintStream JavaDoc out, String JavaDoc indent) {
156         out.println(indent + this);
157         if (nested != null) {
158             for (int i = 0; i < nested.length; i++) {
159                 nested[i].dump(out, indent + " ");
160             }
161         }
162     }
163
164     /**
165      * Get the value of an extension that must be a String.
166      *
167      * @throws javax.jdo.JDOFatalUserException if the value is null
168      */

169     public String JavaDoc getString() {
170         if (value == null) {
171             throw BindingSupportImpl.getInstance().runtime("Expected 'value' attribute for " +
172                     this + "\n" + getContext());
173         }
174         return value;
175     }
176
177     /**
178      * Is the value of this extension the special NO_VALUE ({no})?
179      */

180     public boolean isNoValue() {
181         return value != null && value.equals(NO_VALUE);
182     }
183
184     /**
185      * Get the value of an extension that must be a boolean. A null value
186      * is true.
187      *
188      * @throws javax.jdo.JDOFatalUserException if the value is invalid
189      */

190     public boolean getBoolean() {
191         if (value == null || value.equals("true")) return true;
192         if (value.equals("false")) return false;
193         throw BindingSupportImpl.getInstance().runtime("Expected 'true' or 'false' for " +
194                 this + "\n" + getContext());
195     }
196
197     /**
198      * Get the value of an extension that must be an int.
199      *
200      * @throws javax.jdo.JDOFatalUserException if the value is invalid
201      */

202     public int getInt() {
203         try {
204             if (value != null) return Integer.parseInt(value);
205         } catch (NumberFormatException JavaDoc e) {
206             // ignore
207
}
208         throw BindingSupportImpl.getInstance().runtime("Expected integer value for " +
209                 this + "\n" + getContext());
210     }
211
212     /**
213      * Get the value of an extension that must be one of a set of enumerated
214      * String's. Each valid String must have an int entry in map. The
215      * corresponding int is returned.
216      *
217      * @throws javax.jdo.JDOFatalUserException if the value is not in map
218      */

219     public int getEnum(Map map) {
220         int ans;
221         if (value == null) {
222             ans = Integer.MIN_VALUE;
223         } else {
224             ans = ((Integer JavaDoc)map.get(value)).intValue();
225         }
226         if (ans != Integer.MIN_VALUE) return ans;
227         // build a nice exception message and throw it
228
ArrayList a = new ArrayList(map.size());
229         for (Iterator i = map.keySet().iterator(); i.hasNext();) a.add(i.next());
230         Collections.sort(a);
231         StringBuffer JavaDoc s = new StringBuffer JavaDoc();
232         if (value == null) {
233             s.append("No value attribute");
234         } else {
235             s.append("Invalid value attribute '");
236             s.append(value);
237             s.append('\'');
238         }
239         s.append(": Expected ");
240         int n = a.size();
241         for (int i = 0; i < n; i++) {
242             if (i > 0) {
243                 if (i < n - 1)
244                     s.append(", ");
245                 else
246                     s.append(" or ");
247             }
248             s.append('\'');
249             s.append(a.get(i));
250             s.append('\'');
251         }
252         s.append('\n');
253         s.append(getContext());
254         throw BindingSupportImpl.getInstance().runtime(s.toString());
255     }
256
257     /**
258      * Get the value of an extension that must be the fully qualified name
259      * of a class or a primitive type. The class is loaded using the supplied
260      * classloader.
261      */

262     public Class JavaDoc getType(ClassLoader JavaDoc loader) {
263         String JavaDoc qname = getString();
264         try {
265             return BeanUtils.loadClass(qname, true, loader);
266         } catch (ClassNotFoundException JavaDoc e) {
267             throw BindingSupportImpl.getInstance().runtime("Class " + qname + " not found\n" +
268                     getContext(), e);
269         }
270     }
271
272     /**
273      * Get the value of an extension that must be the fully qualified name
274      * of a class assignable from the supplied class. The class is loaded
275      * using the supplied classloader.
276      */

277     public Class JavaDoc getType(ClassLoader JavaDoc loader, Class JavaDoc requiredType) {
278         Class JavaDoc t = getType(loader);
279         if (requiredType.isAssignableFrom(t)) return t;
280         throw BindingSupportImpl.getInstance().runtime("Class " + t.getName() + " is not a " +
281                 requiredType.getName() + "\n" +
282                 getContext());
283     }
284
285     /**
286      * Create a HashMap of properties from our nested property extensions.
287      * If there are none an empty map is returned.
288      */

289     public HashMap getPropertyMap() {
290         return getPropertyMap(new HashMap(17));
291     }
292
293     /**
294      * Add propertiies to the supplied HashMap.
295      */

296     public HashMap getPropertyMap(HashMap m) {
297         if (nested != null) {
298             int n = nested.length;
299             for (int i = 0; i < n; i++) {
300                 JdoExtension e = nested[i];
301                 if (e.key != PROPERTY) {
302                     throw BindingSupportImpl.getInstance().runtime("Expected property extension: " + e + "\n" +
303                             e.getContext());
304                 }
305                 String JavaDoc v = nested[i].getString();
306                 int pos = v.indexOf('=');
307                 if (pos < 0) {
308                     throw BindingSupportImpl.getInstance().runtime("Invalid value attribute, expected 'key=value': '" +
309                             v + "'\n" + e.getContext());
310                 }
311                 String JavaDoc key = v.substring(0, pos);
312                 v = v.substring(pos + 1);
313                 m.put(key, v);
314             }
315         }
316         return m;
317     }
318
319     /**
320      * Find an extension from an array of extensions.
321      */

322     public static JdoExtension find(int key, JdoExtension[] a) {
323         if (a == null) return null;
324         int n = a.length;
325         for (int i = 0; i < n; i++) if (a[i].key == key) return a[i];
326         return null;
327     }
328
329     /**
330      * Create the extension if it does not exist, else update it if overwrite is true
331      * @param key
332      * @param value
333      * @param overwrite
334      */

335     public void findCreate(int key, String JavaDoc value, boolean overwrite) {
336         if (nested == null) {
337             nested = new JdoExtension[] {createChild(key, value)};
338             return;
339         }
340
341         JdoExtension ext = find(key, nested);
342
343         if (ext == null) {
344             addExtension(createChild(key, value));
345         } else if (overwrite) {
346             ext.value = value;
347         }
348     }
349
350     private JdoExtension createChild(int key, String JavaDoc value) {
351         JdoExtension e = new JdoExtension();
352         e.key = key;
353         e.value = value;
354         e.parent = this;
355         return e;
356     }
357
358     private void addExtension(JdoExtension e) {
359         JdoExtension[] tmp = new JdoExtension[nested.length + 1];
360         System.arraycopy(nested, 0, tmp, 0, nested.length);
361         tmp[nested.length] = e;
362         nested = tmp;
363     }
364
365     /**
366      * Find an extension from an array of extensions.
367      */

368     public static JdoExtension find(int key, JdoElement[] a) {
369         if (a == null) return null;
370         int n = a.length;
371         for (int i = 0; i < n; i++) {
372             if (a[i] instanceof JdoExtension) {
373                 if (((JdoExtension)a[i]).key == key) return (JdoExtension) a[i];
374             }
375         }
376         return null;
377     }
378
379     public static JdoExtension find(int key, String JavaDoc value, JdoExtension[] a) {
380         if (a == null) return null;
381         int n = a.length;
382         for (int i = 0; i < n; i++) if (a[i].key == key && a[i].value.equals(value)) return a[i];
383         return null;
384     }
385
386     /**
387      * Does the any of the nested jdoExtension contain the spec key
388      *
389      * @param key The key to search for.
390      * @return
391      */

392     public boolean contains(int key) {
393         if (nested != null) {
394             for (int i = 0; i < nested.length; i++) {
395                 JdoExtension jdoExtension = nested[i];
396                 if (jdoExtension.key == key) return true;
397             }
398         }
399         return false;
400     }
401
402     /**
403      * Update the 'to' extension with the 'from' extensions. If there is
404      * elements in 'from' that is not in 'to' then add them. If the element is there
405      * then update it value and recursively synchronize its nested elements.
406      *
407      */

408     public static JdoExtension[] synchronize(JdoExtension[] from, JdoExtension[] to) {
409         if (from == null) return to;
410         if (to == null) return from;
411
412         ArrayList newExts = new ArrayList(to.length);
413         for (int i = 0; i < from.length; i++) {
414             boolean found = false;
415             JdoExtension fromElement = from[i];
416
417             for (int j = 0; j < to.length; j++) {
418                 JdoExtension toElement = to[j];
419                 if (fromElement.key == toElement.key) {
420                     switch (fromElement.key) {
421                         case JdoExtension.FIELD:
422                             if (fromElement.value != null
423                                     && fromElement.value.equals(toElement.value)) {
424                                 toElement.nested = JdoExtension.synchronize(fromElement.nested, toElement.nested);
425                             }
426                             break;
427                         case JdoExtension.JDBC_COLUMN:
428                             toElement.nested =
429                                     JdoExtension.synchronize(fromElement.nested,
430                                             toElement.nested);
431                             break;
432                         case JdoExtension.JDBC_COLUMN_NAME:
433                             toElement.value = fromElement.value;
434                             break;
435                     }
436                     found = true;
437                     newExts.add(toElement);
438                     break;
439                 }
440             }
441
442             if (!found) {
443                 newExts.add(fromElement);
444             }
445         }
446
447         JdoExtension[] result = new JdoExtension[newExts.size()];
448         newExts.toArray(result);
449         return result;
450     }
451
452     public static void synchronize3(JdoExtension[] from, JdoExtension[] to,
453             Set exclude, boolean errorOnExclude) {
454         if (from == null) return;
455         if (to == null) return;
456
457         for (int i = 0; i < from.length; i++) {
458             JdoExtension fromElement = from[i];
459             for (int j = 0; j < to.length; j++) {
460                 JdoExtension toElement = to[j];
461                 if (fromElement.key == toElement.key) {
462                     if (exclude.contains(toKeyString(fromElement.key))) {
463                         if (errorOnExclude) {
464                             throw BindingSupportImpl.getInstance().invalidOperation("");
465                         }
466                         return;
467                     }
468                     if (fromElement.value != null) {
469                         if (!fromElement.value.equals(toElement.value)) {
470                             toElement.value = fromElement.value;
471                         }
472                     }
473                     synchronize3(fromElement.nested, toElement.nested, exclude, errorOnExclude);
474                 }
475             }
476         }
477     }
478
479     public static JdoExtension[] synchronize4(JdoExtension[] from, JdoExtension[] to, Set ignore) {
480         if (from == null) return to;
481
482         List toAdd = new ArrayList();
483         for (int i = 0; i < from.length; i++) {
484             JdoExtension fromElement = from[i];
485             if (!ignore.isEmpty()
486                     && ignore.contains(JdoExtension.toKeyString(fromElement.key))) {
487                 continue;
488             }
489             boolean found = false;
490             if (to != null) {
491                 for (int j = 0; j < to.length; j++) {
492                     JdoExtension toElement = to[j];
493                     if (fromElement.key == toElement.key) {
494                         found = true;
495                         if (fromElement.value != null) {
496                             if (!fromElement.value.equals(toElement.value)) {
497                                 toElement.value = fromElement.value;
498                             }
499                         }
500                         toElement.nested = synchronize4(fromElement.nested, toElement.nested, ignore);
501                     }
502                 }
503             }
504             if (!found) {
505                 toAdd.add(fromElement);
506             }
507         }
508         if (!toAdd.isEmpty()) {
509             if (to != null) {
510                 for (int i = 0; i < to.length; i++) {
511                     toAdd.add(to[i]);
512                 }
513             }
514             JdoExtension tmp[] = new JdoExtension[toAdd.size()];
515             toAdd.toArray(tmp);
516             return tmp;
517         }
518         return to;
519     }
520
521     public boolean isFieldAttribute() {
522         if (key == JdoExtensionKeys.DEFAULT_FETCH_GROUP
523                 || key == JdoExtensionKeys.EMBEDDED
524                 || key == JdoExtensionKeys.NULL_VALUE) {
525             return true;
526         }
527         return false;
528     }
529
530     public static void clearKey(int key, int level, JdoExtension[] exts) {
531         if (exts != null) {
532             for (int k = 0; k < exts.length; k++) {
533                 JdoExtension ext1 = exts[k];
534                 if (ext1.key == key) {
535                     ext1.value = null;
536                     break;
537                 } else if (ext1.nested != null) {
538                     for (int l = 0; l < ext1.nested.length; l++) {
539                         JdoExtension ext2 = ext1.nested[l];
540                         if (ext2.key == key) {
541                             ext2.key = -1;
542                         } else if (ext2.nested != null) {
543                             for (int i = 0; i < ext2.nested.length; i++) {
544                                 JdoExtension ext3 = ext2.nested[i];
545                                 if (ext3.key == key) {
546                                     ext3.key = -1;
547                                 }
548                             }
549                         }
550                     }
551                 }
552             }
553         }
554     }
555 }
556
557
Popular Tags