KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > handlers > gen > AssociationGenerator


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 package org.netbeans.mdr.handlers.gen;
20
21 import org.netbeans.mdr.persistence.StorageException;
22 import org.netbeans.mdr.storagemodel.StorableAssociation;
23 import org.netbeans.mdr.storagemodel.StorableObject;
24 import org.netbeans.mdr.util.DebugException;
25 import org.netbeans.mdr.util.Logger;
26 import org.netbeans.mdr.util.MOFConstants;
27 import javax.jmi.model.MultiplicityType;
28 import java.io.DataOutputStream JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.util.*;
31
32 /**
33  *
34  * @author Martin Matula, Dusan Balek
35  * @version
36  */

37 class AssociationGenerator extends HandlerGenerator {
38     private static final String JavaDoc ALL_LINKS_NAME = "refAllLinks"; //NOI18N
39
private static final String JavaDoc ADD_NAME = "add"; //NOI18N
40
private static final String JavaDoc EXISTS_NAME = "exists"; //NOI18N
41
private static final String JavaDoc REMOVE_NAME = "remove"; //NOI18N
42
private static final String JavaDoc QUERY_PREFIX = "get"; //NOI18N
43

44     private static final String JavaDoc M_ADD_NAME = "Add"; //NOI18N
45
private static final String JavaDoc M_ADD_DESC = "(Ljavax/jmi/reflect/RefObject;Ljavax/jmi/reflect/RefObject;)"; //NOI18N
46
private static final String JavaDoc M_ADD_TYPE = "Ljava/lang/Boolean;"; //NOI18N
47
private static final String JavaDoc M_EXISTS_NAME = "Exists"; //NOI18N
48
private static final String JavaDoc M_EXISTS_DESC = "(Ljavax/jmi/reflect/RefObject;Ljavax/jmi/reflect/RefObject;)"; //NOI18N
49
private static final String JavaDoc M_EXISTS_TYPE = "Ljava/lang/Boolean;"; //NOI18N
50
private static final String JavaDoc M_REMOVE_NAME = "Remove"; //NOI18N
51
private static final String JavaDoc M_REMOVE_DESC = "(Ljavax/jmi/reflect/RefObject;Ljavax/jmi/reflect/RefObject;)"; //NOI18N
52
private static final String JavaDoc M_REMOVE_TYPE = "Ljava/lang/Boolean;"; //NOI18N
53
private static final String JavaDoc M_ALL_LINKS_NAME = "AllLinks"; //NOI18N
54
private static final String JavaDoc M_ALL_LINKS_DESC = "()"; //NOI18N
55
private static final String JavaDoc M_ALL_LINKS_TYPE = "Ljava/util/Collection;"; //NOI18N
56
private static final String JavaDoc M_QUERY_NAME = "Query"; //NOI18N
57
private static final String JavaDoc M_QUERY_DESC = "(Ljava/lang/String;Ljavax/jmi/reflect/RefObject;)"; //NOI18N
58
private static final String JavaDoc M_QUERY_TYPE = "Ljava/lang/Object;"; //NOI18N
59

60     private final HashMap dispatchMethods = new HashMap();
61     private final HashMap dispatchEndMethods = new HashMap();
62     
63     AssociationGenerator(String JavaDoc name, Class JavaDoc ifc, Class JavaDoc handler, StorableAssociation storable, Class JavaDoc custom) {
64         super(name, ifc, handler, storable, custom);
65         dispatchEndMethods.put("_query", new HashMap()); //NOI18N
66
}
67     
68     protected MethodInfo[] generateMethods() throws IOException JavaDoc {
69         try {
70             ArrayList methods = new ArrayList();
71         methods.add(generateConstructor());
72             StorableObject[] ends = new StorableObject[2];
73             int i = 0;
74             for (Iterator it = ((List) obj.getMetaObject().getReference(MOFConstants.SH_MODEL_NAMESPACE_CONTENTS)).iterator(); it.hasNext() && i < 2;) {
75                 StorableObject element = (StorableObject) it.next();
76                 String JavaDoc metaTypeName = (String JavaDoc) element.getMetaObject().getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
77                 if (metaTypeName.equals(MOFConstants.SH_MODEL_ASSOCIATION_END))
78                     ends[i++] = element;
79             }
80             String JavaDoc end1Name = (String JavaDoc) ends[0].getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
81             String JavaDoc end1SubstName = TagSupport.getSubstName(ends[0]);
82             String JavaDoc end1Class = TagSupport.getTypeFullName(getAttrType(ends[0]));
83             String JavaDoc end2Name = (String JavaDoc) ends[1].getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME);
84             String JavaDoc end2SubstName = TagSupport.getSubstName(ends[1]);
85             String JavaDoc end2Class = TagSupport.getTypeFullName(getAttrType(ends[1]));
86             // exists(<associationEnd1>, <associationEnd2>)
87
methods.addAll(getAssocMethod(EXISTS_NAME, new String JavaDoc[] {end1Class, end2Class}, "boolean", M_EXISTS_NAME, M_EXISTS_DESC, M_EXISTS_TYPE, null, "_exists")); //NOI18N
88
// <associationEnd1>(<associationEnd2>)
89
if (((Boolean JavaDoc) ends[0].getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_END_IS_NAVIGABLE)).booleanValue()) {
90                 MultiplicityType multiplicity = (MultiplicityType) ends[0].getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_END_MULTIPLICITY);
91                 methods.addAll(getAssocMethod(QUERY_PREFIX + firstUpper(end1SubstName), new String JavaDoc[] {end2Class}, multiplicity.getUpper() == 1 ? end1Class : (multiplicity.isOrdered() ? DT_ORDERED : DT_MULTIVALUED), M_QUERY_NAME, M_QUERY_DESC, M_QUERY_TYPE, end2Name, "_query")); //NOI18N
92
}
93             // <associationEnd2>(<associationEnd1>)
94
if (((Boolean JavaDoc) ends[1].getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_END_IS_NAVIGABLE)).booleanValue()) {
95                 MultiplicityType multiplicity = (MultiplicityType) ends[1].getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_END_MULTIPLICITY);
96                 methods.addAll(getAssocMethod(QUERY_PREFIX + firstUpper(end2SubstName), new String JavaDoc[] {end1Class}, multiplicity.getUpper() == 1 ? end2Class : (multiplicity.isOrdered() ? DT_ORDERED : DT_MULTIVALUED), M_QUERY_NAME, M_QUERY_DESC, M_QUERY_TYPE, end1Name, "_query")); //NOI18N
97
}
98             if (((Boolean JavaDoc) ends[0].getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_END_IS_CHANGEABLE)).booleanValue() && ((Boolean JavaDoc) ends[1].getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_END_IS_CHANGEABLE)).booleanValue()) {
99                 // add(<associationEnd1>, <associationEnd2>)
100
methods.addAll(getAssocMethod(ADD_NAME, new String JavaDoc[] {end1Class, end2Class}, "boolean", M_ADD_NAME, M_ADD_DESC, M_ADD_TYPE, null, "_add")); //NOI18N
101
// remove(<associationEnd1>, <associationEnd2>)
102
methods.addAll(getAssocMethod(REMOVE_NAME, new String JavaDoc[] {end1Class, end2Class}, "boolean", M_REMOVE_NAME, M_REMOVE_DESC, M_REMOVE_TYPE, null, "_remove")); //NOI18N
103
}
104             methods.addAll(getAssocMethod(ALL_LINKS_NAME, new String JavaDoc[0], DT_MULTIVALUED, M_ALL_LINKS_NAME, M_ALL_LINKS_DESC, M_ALL_LINKS_TYPE, null, "_all")); //NOI18N
105
methods.add(getDispatchEndMethod("_query", new String JavaDoc[] {"java.lang.String", "javax.jmi.reflect.RefObject"}, "java.lang.Object", (HashMap) dispatchEndMethods.get("_query"))); //NOI18N
106
methods.add(getDispatchMethod("_remove", new String JavaDoc[] {"javax.jmi.reflect.RefObject", "javax.jmi.reflect.RefObject"}, "boolean", dispatchMethods.get("_remove"))); //NOI18N
107
methods.add(getDispatchMethod("_exists", new String JavaDoc[] {"javax.jmi.reflect.RefObject", "javax.jmi.reflect.RefObject"}, "boolean", dispatchMethods.get("_exists"))); //NOI18N
108
methods.add(getDispatchMethod("_add", new String JavaDoc[] {"javax.jmi.reflect.RefObject", "javax.jmi.reflect.RefObject"}, "boolean", dispatchMethods.get("_add"))); //NOI18N
109
methods.add(getDispatchMethod("_all", new String JavaDoc[0], DT_MULTIVALUED, dispatchMethods.get("_all"))); //NOI18N
110
return (MethodInfo[]) methods.toArray(new MethodInfo[methods.size()]);
111         } catch (Exception JavaDoc e) {
112             throw (DebugException) Logger.getDefault().annotate(new DebugException(), e);
113         }
114     }
115     
116     protected String JavaDoc getConstructorDescriptor() {
117         return "(Lorg/netbeans/mdr/storagemodel/StorableAssociation;)V"; //NOI18N
118
}
119     
120     protected Collection getAssocMethod(String JavaDoc methodName, String JavaDoc[] parameterTypes, String JavaDoc returnType, String JavaDoc handlerName, String JavaDoc handlerDescriptor, String JavaDoc handlerType, String JavaDoc featureName, String JavaDoc dispatchMethod) throws IOException JavaDoc, StorageException {
121         if (featureName != null) {
122             HashMap item = (HashMap) dispatchEndMethods.get(dispatchMethod);
123             item.put(featureName, new MethodDescHolder(methodName, parameterTypes, returnType));
124         } else {
125             dispatchMethods.put(dispatchMethod, new MethodDescHolder(methodName, parameterTypes, returnType));
126         }
127         if (((Boolean JavaDoc) obj.getMetaObject().getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_IS_DERIVED)).booleanValue()) {
128             return Collections.EMPTY_LIST;
129         } else {
130             return getHandlerMethod(methodName, parameterTypes, returnType, handlerName, handlerDescriptor, handlerType, featureName);
131         }
132     }
133     
134     protected MethodInfo getDispatchMethod(String JavaDoc methodName, String JavaDoc[] parameterTypes, String JavaDoc returnType, Object JavaDoc delegateObject) throws IOException JavaDoc {
135         String JavaDoc desc = getMethodDescriptor(parameterTypes, returnType);
136         MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL);
137
138         // all the parameters are of object type, thus each takes only 1 slot
139
int localSlot0 = 1 + parameterTypes.length;
140
141         DataOutputStream JavaDoc out = new DataOutputStream JavaDoc(minfo.getCodeStream());
142         
143         if (delegateObject instanceof MethodDescHolder) {
144             MethodDescHolder delegate = (MethodDescHolder) delegateObject;
145         
146             code_aload(0, out);
147             for (int i = 1; i < localSlot0; i++) {
148                 code_aload(i, out);
149                 out.writeByte(opc_checkcast);
150                 out.writeShort(cp.getClass(dotToSlash(delegate.getParameterTypes()[i - 1])));
151             }
152         
153             // if it is equal, return result of a proper method
154
out.writeByte(opc_invokevirtual);
155             out.writeShort(cp.getMethodRef(dotToSlash(className), delegate.getName(), getMethodDescriptor(delegate.getParameterTypes(), delegate.getReturnType())));
156             if (returnType.equals("void")) //NOI18N
157
out.writeByte(opc_return);
158             else if (returnType.equals("boolean")) //NOI18N
159
out.writeByte(opc_ireturn);
160             else
161                 out.writeByte(opc_areturn);
162         }
163         else {
164             // if the field was not found, throw an exception
165
out.writeByte(opc_new); // new
166
out.writeShort(cp.getClass("org/netbeans/mdr/util/DebugException")); //NOI18N
167
out.writeByte(opc_dup); // dup
168
out.writeByte(opc_invokespecial);
169             out.writeShort(cp.getMethodRef("org/netbeans/mdr/util/DebugException", "<init>", "()V")); //NOI18N
170
out.writeByte(opc_athrow);
171         }
172         minfo.setMaxStack((short)10);
173         minfo.setMaxLocals((short)(localSlot0 + 2));
174         
175         return minfo;
176     }
177     
178     protected MethodInfo getDispatchEndMethod(String JavaDoc methodName, String JavaDoc[] parameterTypes, String JavaDoc returnType, HashMap ends) throws IOException JavaDoc {
179         String JavaDoc desc = getMethodDescriptor(parameterTypes, returnType);
180         MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL);
181
182         // all the parameters are of object type, thus each takes only 1 slot
183
int localSlot0 = parameterTypes.length + 1;
184         
185         DataOutputStream JavaDoc out = new DataOutputStream JavaDoc(minfo.getCodeStream());
186         
187         code_aload(0, out);
188         
189         for (Iterator it = ends.keySet().iterator(); it.hasNext();) {
190             String JavaDoc endName = (String JavaDoc) it.next();
191             MethodDescHolder item = (MethodDescHolder) ends.get(endName);
192             
193             // load name of feature
194
code_ldc(cp.getString(endName), out);
195             
196             //compare it with passed name
197
code_aload(1, out);
198             out.writeByte(opc_invokevirtual);
199             out.writeShort(cp.getMethodRef("java/lang/String", "equals", "(Ljava/lang/Object;)Z")); //NOI18N
200

201             // if it is not equal, continue processing
202
out.writeByte(opc_ifeq);
203             out.writeShort((short) (7 + 5 * (localSlot0 - 2)));
204             
205             // if it is equal, return result of a proper method
206
// but first recast the parameters to see if they are of the correct type
207
for (int i = 2; i < localSlot0; i++) {
208                 out.writeByte(opc_aload);
209                 out.writeByte(i);
210                 out.writeByte(opc_checkcast);
211                 out.writeShort(cp.getClass(dotToSlash(item.getParameterTypes()[i - 2])));
212             }
213
214             out.writeByte(opc_invokevirtual);
215             out.writeShort(cp.getMethodRef(dotToSlash(className), item.getName(), getMethodDescriptor(item.getParameterTypes(), item.getReturnType())));
216             if (returnType.equals("void")) //NOI18N
217
out.writeByte(opc_return);
218             else
219                 out.writeByte(opc_areturn);
220         }
221         
222         // if the field was not found, throw an exception
223
out.writeByte(opc_new); // new
224
out.writeShort(cp.getClass("javax/jmi/reflect/InvalidNameException")); //NOI18N
225
out.writeByte(opc_dup); // dup
226
code_aload(1, out);
227         out.writeByte(opc_invokespecial);
228         out.writeShort(cp.getMethodRef("javax/jmi/reflect/InvalidNameException", "<init>", "(Ljava/lang/String;)V")); //NOI18N
229
out.writeByte(opc_athrow);
230         
231         minfo.setMaxStack((short)10);
232         minfo.setMaxLocals((short) (localSlot0 + 2));
233         
234         return minfo;
235     }
236 }
237
Popular Tags