1 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 ; 29 import java.io.IOException ; 30 import java.util.*; 31 32 37 class AssociationGenerator extends HandlerGenerator { 38 private static final String ALL_LINKS_NAME = "refAllLinks"; private static final String ADD_NAME = "add"; private static final String EXISTS_NAME = "exists"; private static final String REMOVE_NAME = "remove"; private static final String QUERY_PREFIX = "get"; 44 private static final String M_ADD_NAME = "Add"; private static final String M_ADD_DESC = "(Ljavax/jmi/reflect/RefObject;Ljavax/jmi/reflect/RefObject;)"; private static final String M_ADD_TYPE = "Ljava/lang/Boolean;"; private static final String M_EXISTS_NAME = "Exists"; private static final String M_EXISTS_DESC = "(Ljavax/jmi/reflect/RefObject;Ljavax/jmi/reflect/RefObject;)"; private static final String M_EXISTS_TYPE = "Ljava/lang/Boolean;"; private static final String M_REMOVE_NAME = "Remove"; private static final String M_REMOVE_DESC = "(Ljavax/jmi/reflect/RefObject;Ljavax/jmi/reflect/RefObject;)"; private static final String M_REMOVE_TYPE = "Ljava/lang/Boolean;"; private static final String M_ALL_LINKS_NAME = "AllLinks"; private static final String M_ALL_LINKS_DESC = "()"; private static final String M_ALL_LINKS_TYPE = "Ljava/util/Collection;"; private static final String M_QUERY_NAME = "Query"; private static final String M_QUERY_DESC = "(Ljava/lang/String;Ljavax/jmi/reflect/RefObject;)"; private static final String M_QUERY_TYPE = "Ljava/lang/Object;"; 60 private final HashMap dispatchMethods = new HashMap(); 61 private final HashMap dispatchEndMethods = new HashMap(); 62 63 AssociationGenerator(String name, Class ifc, Class handler, StorableAssociation storable, Class custom) { 64 super(name, ifc, handler, storable, custom); 65 dispatchEndMethods.put("_query", new HashMap()); } 67 68 protected MethodInfo[] generateMethods() throws IOException { 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 metaTypeName = (String ) 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 end1Name = (String ) ends[0].getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME); 81 String end1SubstName = TagSupport.getSubstName(ends[0]); 82 String end1Class = TagSupport.getTypeFullName(getAttrType(ends[0])); 83 String end2Name = (String ) ends[1].getAttribute(MOFConstants.SH_MODEL_MODEL_ELEMENT_NAME); 84 String end2SubstName = TagSupport.getSubstName(ends[1]); 85 String end2Class = TagSupport.getTypeFullName(getAttrType(ends[1])); 86 methods.addAll(getAssocMethod(EXISTS_NAME, new String [] {end1Class, end2Class}, "boolean", M_EXISTS_NAME, M_EXISTS_DESC, M_EXISTS_TYPE, null, "_exists")); if (((Boolean ) 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 [] {end2Class}, multiplicity.getUpper() == 1 ? end1Class : (multiplicity.isOrdered() ? DT_ORDERED : DT_MULTIVALUED), M_QUERY_NAME, M_QUERY_DESC, M_QUERY_TYPE, end2Name, "_query")); } 93 if (((Boolean ) 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 [] {end1Class}, multiplicity.getUpper() == 1 ? end2Class : (multiplicity.isOrdered() ? DT_ORDERED : DT_MULTIVALUED), M_QUERY_NAME, M_QUERY_DESC, M_QUERY_TYPE, end1Name, "_query")); } 98 if (((Boolean ) ends[0].getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_END_IS_CHANGEABLE)).booleanValue() && ((Boolean ) ends[1].getAttribute(MOFConstants.SH_MODEL_ASSOCIATION_END_IS_CHANGEABLE)).booleanValue()) { 99 methods.addAll(getAssocMethod(ADD_NAME, new String [] {end1Class, end2Class}, "boolean", M_ADD_NAME, M_ADD_DESC, M_ADD_TYPE, null, "_add")); methods.addAll(getAssocMethod(REMOVE_NAME, new String [] {end1Class, end2Class}, "boolean", M_REMOVE_NAME, M_REMOVE_DESC, M_REMOVE_TYPE, null, "_remove")); } 104 methods.addAll(getAssocMethod(ALL_LINKS_NAME, new String [0], DT_MULTIVALUED, M_ALL_LINKS_NAME, M_ALL_LINKS_DESC, M_ALL_LINKS_TYPE, null, "_all")); methods.add(getDispatchEndMethod("_query", new String [] {"java.lang.String", "javax.jmi.reflect.RefObject"}, "java.lang.Object", (HashMap) dispatchEndMethods.get("_query"))); methods.add(getDispatchMethod("_remove", new String [] {"javax.jmi.reflect.RefObject", "javax.jmi.reflect.RefObject"}, "boolean", dispatchMethods.get("_remove"))); methods.add(getDispatchMethod("_exists", new String [] {"javax.jmi.reflect.RefObject", "javax.jmi.reflect.RefObject"}, "boolean", dispatchMethods.get("_exists"))); methods.add(getDispatchMethod("_add", new String [] {"javax.jmi.reflect.RefObject", "javax.jmi.reflect.RefObject"}, "boolean", dispatchMethods.get("_add"))); methods.add(getDispatchMethod("_all", new String [0], DT_MULTIVALUED, dispatchMethods.get("_all"))); return (MethodInfo[]) methods.toArray(new MethodInfo[methods.size()]); 111 } catch (Exception e) { 112 throw (DebugException) Logger.getDefault().annotate(new DebugException(), e); 113 } 114 } 115 116 protected String getConstructorDescriptor() { 117 return "(Lorg/netbeans/mdr/storagemodel/StorableAssociation;)V"; } 119 120 protected Collection getAssocMethod(String methodName, String [] parameterTypes, String returnType, String handlerName, String handlerDescriptor, String handlerType, String featureName, String dispatchMethod) throws IOException , 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 ) 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 methodName, String [] parameterTypes, String returnType, Object delegateObject) throws IOException { 135 String desc = getMethodDescriptor(parameterTypes, returnType); 136 MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL); 137 138 int localSlot0 = 1 + parameterTypes.length; 140 141 DataOutputStream out = new DataOutputStream (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 out.writeByte(opc_invokevirtual); 155 out.writeShort(cp.getMethodRef(dotToSlash(className), delegate.getName(), getMethodDescriptor(delegate.getParameterTypes(), delegate.getReturnType()))); 156 if (returnType.equals("void")) out.writeByte(opc_return); 158 else if (returnType.equals("boolean")) out.writeByte(opc_ireturn); 160 else 161 out.writeByte(opc_areturn); 162 } 163 else { 164 out.writeByte(opc_new); out.writeShort(cp.getClass("org/netbeans/mdr/util/DebugException")); out.writeByte(opc_dup); out.writeByte(opc_invokespecial); 169 out.writeShort(cp.getMethodRef("org/netbeans/mdr/util/DebugException", "<init>", "()V")); 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 methodName, String [] parameterTypes, String returnType, HashMap ends) throws IOException { 179 String desc = getMethodDescriptor(parameterTypes, returnType); 180 MethodInfo minfo = new MethodInfo(methodName, desc, ACC_PUBLIC | ACC_FINAL); 181 182 int localSlot0 = parameterTypes.length + 1; 184 185 DataOutputStream out = new DataOutputStream (minfo.getCodeStream()); 186 187 code_aload(0, out); 188 189 for (Iterator it = ends.keySet().iterator(); it.hasNext();) { 190 String endName = (String ) it.next(); 191 MethodDescHolder item = (MethodDescHolder) ends.get(endName); 192 193 code_ldc(cp.getString(endName), out); 195 196 code_aload(1, out); 198 out.writeByte(opc_invokevirtual); 199 out.writeShort(cp.getMethodRef("java/lang/String", "equals", "(Ljava/lang/Object;)Z")); 201 out.writeByte(opc_ifeq); 203 out.writeShort((short) (7 + 5 * (localSlot0 - 2))); 204 205 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")) out.writeByte(opc_return); 218 else 219 out.writeByte(opc_areturn); 220 } 221 222 out.writeByte(opc_new); out.writeShort(cp.getClass("javax/jmi/reflect/InvalidNameException")); out.writeByte(opc_dup); code_aload(1, out); 227 out.writeByte(opc_invokespecial); 228 out.writeShort(cp.getMethodRef("javax/jmi/reflect/InvalidNameException", "<init>", "(Ljava/lang/String;)V")); 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 |