KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > jmi > mapping > GenericMapper


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.lib.jmi.mapping;
21
22 import org.netbeans.lib.jmi.util.TagProvider;
23 import javax.jmi.model.*;
24 import javax.jmi.reflect.*;
25 import java.io.IOException JavaDoc;
26 import java.util.*;
27
28 /**
29  * Generates java interfaces for specified meta objects or whole meta model.
30  *
31  * @author Dusan Balek, Martin Matula
32  */

33 public abstract class GenericMapper {
34     protected static String JavaDoc PACKAGE_POSTFIX = "Package"; //NOI18N
35
protected static String JavaDoc CLASS_POSTFIX = "Class"; //NOI18N
36
protected static String JavaDoc ENUM_POSTFIX = "Enum"; //NOI18N
37

38     // name of exception used as an ancestor for all the mapped exceptions
39
protected static final String JavaDoc DT_EXCEPTION = "javax.jmi.reflect.RefException"; //NOI18N
40
// name of package used as an ancestor for all the mapped packages
41
protected static final String JavaDoc DT_PACKAGE = "javax.jmi.reflect.RefPackage"; //NOI18N
42
// name of association used as an ancestor for all the mapped associations
43
protected static final String JavaDoc DT_ASSOCIATION = "javax.jmi.reflect.RefAssociation"; //NOI18N
44
// name of class proxy used as an ancestor for all the mapped calss proxies
45
protected static final String JavaDoc DT_CLASS = "javax.jmi.reflect.RefClass"; //NOI18N
46
// name of class instance used as an ancestor for all the mapped class instances
47
protected static final String JavaDoc DT_INSTANCE = "javax.jmi.reflect.RefObject"; //NOI18N
48
// name of structure used as an ancestor for all the mapped strucutres
49
protected static final String JavaDoc DT_STRUCTURE = "javax.jmi.reflect.RefStruct"; //NOI18N
50
// name of enumeration used as an ancestor for all the mapped enumerations
51
protected static final String JavaDoc DT_ENUMERATION = "javax.jmi.reflect.RefEnum"; //NOI18N
52
// name of java type used to represent multivalued unordered values
53
protected static final String JavaDoc DT_MULTIVALUED = "java.util.Collection"; //NOI18N
54
// name of java type used to represent multivalued ordered values
55
protected static final String JavaDoc DT_ORDERED = "java.util.List"; //NOI18N
56
// name of java type uset to represent values of type ANY
57
protected static final String JavaDoc DT_ANY = "java.lang.Object"; //NOI18N
58

59     protected final TagProvider tagProvider = new TagProvider();
60     
61     // used for storing already visited object so that the interfaces
62
// are not generated twice for them
63
protected final Set visited = new HashSet();
64
65     // conversion table between object type names and primitive type names
66
protected static final HashMap objectToPrimitive = new HashMap(7);
67     static {
68         objectToPrimitive.put("java.lang.Short", "short"); //NOI18N
69
objectToPrimitive.put("java.lang.Integer", "int"); //NOI18N
70
objectToPrimitive.put("java.lang.Float", "float"); //NOI18N
71
objectToPrimitive.put("java.lang.Double", "double"); //NOI18N
72
objectToPrimitive.put("java.lang.Boolean", "boolean"); //NOI18N
73
objectToPrimitive.put("java.lang.Character", "char"); //NOI18N
74
objectToPrimitive.put("java.lang.Long", "long"); //NOI18N
75
}
76     
77     // helper function for converting first character of the string to upper case
78
protected static String JavaDoc firstUpper(String JavaDoc text) {
79         if (text == null) return null;
80         if (text.length() < 2) return text.toUpperCase(Locale.US);
81         return text.substring(0, 1).toUpperCase(Locale.US) + text.substring(1);
82     }
83
84     // helper function for converting first character of the string to lower case
85
protected static String JavaDoc firstLower(String JavaDoc text) {
86         if (text == null) return null;
87         if (text.length() < 2) return text.toLowerCase(Locale.US);
88         return text.substring(0, 1).toLowerCase(Locale.US) + text.substring(1);
89     }
90
91     // helper function for removing underscore characters from a structure member name
92
protected static String JavaDoc removeUnderscores(String JavaDoc text) {
93         StringBuffer JavaDoc result = new StringBuffer JavaDoc(text.length());
94         int pos = 0;
95         int oldPos = 0;
96         String JavaDoc firstChar;
97
98         while (oldPos <= text.length()) {
99             if ((pos = text.indexOf('_', oldPos)) == -1) {
100                 pos = text.length() + 1;
101             }
102             if (pos - oldPos > 1) {
103                 firstChar = text.substring(oldPos, oldPos + 1);
104                 // convert the letter following the "_" to uppercase it
105
// in case it is not the first character
106
if (oldPos > 0) {
107                     firstChar = firstChar.toUpperCase(Locale.US);
108                 }
109                 // and append it
110
result.append(firstChar);
111                 // append the rest of the string to the next "_"
112
if (pos > text.length()) {
113                     result.append(text.substring(oldPos + 1));
114                 } else {
115                     result.append(text.substring(oldPos + 1, pos));
116                 }
117             }
118             oldPos = pos + 1;
119         }
120
121         return result.toString();
122     }
123     
124     // method for parsing the package name
125
private static List parseDots(String JavaDoc packageName) {
126         int position;
127         String JavaDoc name = packageName;
128         ArrayList result = new ArrayList();
129
130         while ((position = name.indexOf('.')) > 0) {
131             result.add(name.substring(0, position));
132             name = name.substring(position + 1);
133         }
134
135         if (position != 0) {
136             result.add(name);
137         }
138
139         return result;
140     }
141
142     // resolves datatype of typed element with aliases support
143
protected Classifier getAttrType(TypedElement attr) {
144         Classifier curType = attr.getType();
145         Classifier attrType = (Classifier) aliasesCache.get(curType);
146
147         if (attrType == null) {
148             attrType = curType;
149             if (curType instanceof AliasType) {
150                 attrType = getAttrType((TypedElement) curType);
151             }
152             // put type mapping into cache
153
aliasesCache.put(curType, attrType);
154         }
155
156         return attrType;
157     }
158     
159     protected static final int GENERIC_STYLE_NONE = 0;
160     protected static final int GENERIC_STYLE_FAKE = 1;
161     protected static final int GENERIC_STYLE_REAL = 2;
162
163     // returns correct type name for attribute or reference or parameter (depending on the multiplicity type)
164
protected String JavaDoc getTypeName(StructuralFeature f) {
165         return getTypeName(f, GENERIC_STYLE_NONE);
166     }
167     protected String JavaDoc getTypeName(StructuralFeature f, int genericStyle) {
168         return getTypeName(f, f.getMultiplicity(), genericStyle);
169     }
170     protected String JavaDoc getTypeName(Parameter p) {
171         return getTypeName(p, GENERIC_STYLE_NONE);
172     }
173     protected String JavaDoc getTypeName(Parameter p, int genericStyle) {
174         return getTypeName(p, p.getMultiplicity(), genericStyle);
175     }
176     private String JavaDoc getTypeName(TypedElement te, MultiplicityType mp, int genericStyle) {
177         String JavaDoc n = getTypeName(getAttrType(te));
178         if (n == null || n.equals("null")) { // NOI18N
179
throw new IllegalStateException JavaDoc("No type name for " + te); // NOI18N
180
}
181         if (mp.getUpper() > 1 || mp.getUpper() == -1) {
182             String JavaDoc rawname = mp.isOrdered() ? DT_ORDERED : DT_MULTIVALUED;
183             switch (genericStyle) {
184             case GENERIC_STYLE_NONE:
185                 return rawname;
186             case GENERIC_STYLE_FAKE:
187                 return rawname + "/*<" + n + ">*/"; // NOI18N
188
case GENERIC_STYLE_REAL:
189                 return rawname + "<" + n + ">"; // NOI18N
190
default:
191                 throw new IllegalArgumentException JavaDoc("Bad genericStyle: " + genericStyle); // NOI18N
192
}
193         } else if (mp.getLower() < 1) {
194             return n;
195         } else {
196             return getPrimitiveName(n);
197         }
198     }
199     
200     //protected String getCollectionTypeName(String rawname, )
201

202     protected String JavaDoc getTypeName2(TypedElement te) {
203         return getPrimitiveName(getTypeName(getAttrType(te)));
204     }
205     
206     // resolves datatype name
207
protected String JavaDoc getTypeName(Classifier type) {
208         String JavaDoc result = (String JavaDoc) typeNameCache.get(type);
209
210         if (result == null) {
211             result = tagProvider.getDataTypeName(type);
212             typeNameCache.put(type, result);
213         }
214
215         return result;
216     }
217
218     // converts object type name to primitive type name
219
protected String JavaDoc getPrimitiveName(String JavaDoc typeName) {
220         String JavaDoc name = (String JavaDoc) objectToPrimitive.get(typeName);
221         return name == null ? typeName : name;
222     }
223     
224     // returns true if the attribute can be mapped to primitive type
225
protected static boolean canBePrimitive(String JavaDoc typeName) {
226         return (objectToPrimitive.get(typeName) != null);
227     }
228
229     // cache for datatype aliases
230
protected final Hashtable aliasesCache = new Hashtable(100);
231     // cache for type names
232
protected final Hashtable typeNameCache = new Hashtable(100);
233     
234     // template methods -----------------------------------------------------------------------------------------------------
235

236     // generates instance interface for a given class
237
protected abstract void classInstanceTemplate(javax.jmi.model.MofClass objClass) throws IOException JavaDoc;
238     // generates proxy interface for a given class
239
protected abstract void classProxyTemplate(javax.jmi.model.MofClass objClass) throws IOException JavaDoc;
240
241     // generates interface for a given association
242
protected abstract void associationTemplate(Association objAssociation) throws IOException JavaDoc;
243     
244     protected abstract void packageTemplate(MofPackage objPackage) throws IOException JavaDoc;
245     
246     // generates class for an exception
247
protected abstract void exceptionTemplate(MofException objException) throws IOException JavaDoc;
248     
249     // generates interface for an enumeration
250
protected abstract void enumerationInterfaceTemplate(EnumerationType objEnumeration) throws IOException JavaDoc;
251     // generates class for an enumeration
252
protected abstract void enumerationClassTemplate(EnumerationType objEnumeration) throws IOException JavaDoc;
253
254     // generates interface for a structure
255
protected abstract void structureTemplate(StructureType objStructure) throws IOException JavaDoc;
256
257     // public ---------------------------------------------------------------------------------------------------------------
258

259     public GenericMapper() { }
260     
261     // stream handling ------------------------------------------------------------------------------------------------------
262

263     /** Called when the mapper is about to start writing a new interface or class.
264      * The subclass should open the output stream or whatever it is going to write to.
265      * @return true if the stream was created;
266      * false if this interface/class should be skipped.
267      */

268     protected abstract boolean createStream(List pkg, String JavaDoc filename) throws IOException JavaDoc;
269     /** Called to close the output stream opened by {@link #closeStream}.
270      * closeStream is called once for every time that createStream returns
271      * true.
272      */

273     protected abstract void closeStream() throws IOException JavaDoc;
274     
275     private boolean streamOpen = false;
276     private boolean switchStream(ModelElement me, String JavaDoc suffix) throws IOException JavaDoc {
277         if (streamOpen) {
278             streamOpen = false;
279             closeStream();
280         }
281         streamOpen = createStream(parseDots(tagProvider.getTypePrefix(me)),
282             tagProvider.getSubstName(me) + suffix);
283         return streamOpen;
284     }
285
286     // implementation of Visotor interface ----------------------------------------------------------------------------------
287

288     /** <P>
289      * The implementation does nothing because there is nothing to map on RefAssociation.
290      * </P>
291      * @param refAssociation Reference to a RefAssociation object.
292      */

293     public void visitRefAssociation(RefAssociation refAssociation) throws IOException JavaDoc {
294 // Logger.getDefault().log("generating association proxy...");
295
visitRefObject(refAssociation.refMetaObject());
296     }
297
298     /** <P>
299      * Generates the interfaces for all the instances created by the passed class proxy.
300      * </P>
301      * @param refClass Reference to a class proxy.
302      */

303     public void visitRefClass(RefClass refClass) throws IOException JavaDoc {
304 // Logger.getDefault().log("generating class proxy...");
305

306         if (refClass.refImmediatePackage() instanceof ModelPackage) {
307             for (Iterator it = refClass.refAllOfClass().iterator(); it.hasNext();) {
308                 visitRefObject((RefObject) it.next());
309             }
310         }
311     }
312
313     /** <P>
314      * Generates interfaces for the passed object instance.
315      * </P>
316      * @param refObject Reference to a class instance.
317      */

318     public void visitRefObject(RefObject refObject) throws IOException JavaDoc {
319         if (visited.contains(refObject) || !(refObject instanceof Namespace)) {
320             return;
321         }
322         Namespace outermost = (Namespace) refObject;
323         for (;;) {
324             Namespace container = outermost.getContainer();
325             if (container == null)
326                 break;
327             outermost = container;
328         }
329         if (!(outermost instanceof MofPackage)) {
330             return;
331         }
332         boolean ignoreLifecycle = false;
333         String JavaDoc ignoreLifecycleString = tagProvider.getTagValue(outermost, TagProvider.TAGID_IGNORE_LIFECYCLE);
334         if (ignoreLifecycleString != null) {
335             if (ignoreLifecycleString.equals("true")) //NOI18N
336
ignoreLifecycle = true;
337             // else if (!ignoreLifecycle.equals("false")) ... this is against the JMI spec
338
}
339         
340         try {
341             if (refObject instanceof Association) {
342 // Logger.getDefault().log("generating association... " + ((ModelElement) refObject).getName());
343
if (!ignoreLifecycle && switchStream((Association)refObject, "")) //NOI18N
344
associationTemplate((Association)refObject);
345             } else if (refObject instanceof MofClass || refObject instanceof MofPackage) {
346                 GeneralizableElement elm = (GeneralizableElement) refObject;
347                 visited.add(elm);
348                 for (Iterator it = elm.getSupertypes().iterator(); it.hasNext();) {
349                     visitRefObject((RefObject) it.next());
350                 }
351                 Collection contents = elm.getContents();
352                 for (Iterator it = contents.iterator(); it.hasNext();) {
353                     visitRefObject((RefObject) it.next());
354                 }
355                 if (elm instanceof MofPackage) {
356 // Logger.getDefault().log("generating package... " + ((ModelElement) refObject).getName());
357
if (!ignoreLifecycle && switchStream(elm, PACKAGE_POSTFIX))
358                         packageTemplate((MofPackage) elm);
359                 } else {
360 // Logger.getDefault().log("generating class... " + ((ModelElement) refObject).getName());
361
if (switchStream(elm, "")) //NOI18N
362
classInstanceTemplate((MofClass) elm);
363                     if (!ignoreLifecycle && switchStream(elm, CLASS_POSTFIX))
364                         classProxyTemplate((MofClass) elm);
365                 }
366             } else if (refObject instanceof EnumerationType) {
367 // Logger.getDefault().log("generating enumeration... " + ((ModelElement) refObject).getName());
368
final EnumerationType et = (EnumerationType) refObject;
369                 if (switchStream(et, "")) //NOI18N
370
enumerationInterfaceTemplate(et);
371                 if (switchStream(et, ENUM_POSTFIX))
372                     enumerationClassTemplate(et);
373             } else if (refObject instanceof StructureType) {
374 // Logger.getDefault().log("generating structure... " + ((ModelElement) refObject).getName());
375
if (switchStream((StructureType)refObject, "")) //NOI18N
376
structureTemplate((StructureType)refObject);
377             } else if (refObject instanceof MofException) {
378 // Logger.getDefault().log("generating exception... " + ((ModelElement) refObject).getName());
379
if (switchStream((MofException)refObject, "")) //NOI18N
380
exceptionTemplate((MofException)refObject);
381             } else {
382 // Logger.getDefault().log("nothing will be generated for type: " + refObject.getClass());
383
}
384         } finally {
385             if (streamOpen) {
386                 streamOpen = false;
387                 closeStream();
388             }
389         }
390     }
391
392     /** <P>
393      * Generates interfaces for all objects created within the passed package proxy
394      * </P>
395      * @param refPackage Reference to a package proxy.
396      */

397     public void visitRefPackage(RefPackage refPackage) throws IOException JavaDoc {
398         //Logger.getDefault().log("generating package proxy...");
399

400         if (refPackage instanceof ModelPackage) {
401             ModelPackage pkg = (ModelPackage) refPackage;
402             ModelElement element;
403
404             for (Iterator it = pkg.getMofPackage().refAllOfClass().iterator(); it.hasNext();) {
405                 element = (ModelElement) it.next();
406                 if (element.getContainer() == null) {
407                     visitRefObject(element);
408                 }
409             }
410         }
411     }
412     
413     public void visitRefBaseObject(RefBaseObject object) throws IOException JavaDoc {
414         if (object instanceof RefPackage) {
415             visitRefPackage((RefPackage) object);
416         } else if (object instanceof RefObject) {
417             visitRefObject((RefObject) object);
418         } else if (object instanceof RefAssociation) {
419             visitRefAssociation((RefAssociation) object);
420         } else if (object instanceof RefClass) {
421             visitRefClass((RefClass) object);
422         }
423     }
424 }
425
Popular Tags