/** * Constructor, taking the meta data for the field, and the table it is mapped to. * * @param mmd MetaData for the field. * @param table Table definition */ public RDBMSStoreData(AbstractMemberMetaData mmd, Table table) { super(mmd.getFullFieldName(), mmd, SCO_TYPE, null); if (table == null) { throw new NullPointerException("table should not be null"); } this.table = table; this.tableName = table.toString(); this.tableOwner = true; this.tableIdentifier = table.getIdentifier(); String interfaceName = (table.getStoreManager().getMetaDataManager().isPersistentInterface(mmd.getType().getName()) ? mmd.getType().getName() : null); if (interfaceName != null) { this.interfaceName = interfaceName; } }
/** * Constructor. * * @param enhancer ClassEnhancer * @param fmd MetaData for the field we are generating for */ public JdoSetViaCheck(ClassEnhancer enhancer, AbstractMemberMetaData fmd) { super( enhancer, enhancer.getNamer().getSetMethodPrefixMethodName() + fmd.getName(), (fmd.isPublic() ? Opcodes.ACC_PUBLIC : 0) | (fmd.isProtected() ? Opcodes.ACC_PROTECTED : 0) | (fmd.isPrivate() ? Opcodes.ACC_PRIVATE : 0) | Opcodes.ACC_STATIC, null, null, null); // Set the arg types/names argTypes = new Class[] {getClassEnhancer().getClassBeingEnhanced(), fmd.getType()}; argNames = new String[] {"objPC", "val"}; this.fmd = fmd; }
/* (non-Javadoc) * @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchObjectField(int) */ @Override public Object fetchObjectField(int fieldNumber) { ClassLoaderResolver clr = ec.getClassLoaderResolver(); AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber); RelationType relationType = mmd.getRelationType(clr); EmbeddedMetaData embmd = mmds.get(0).getEmbeddedMetaData(); if (mmds.size() == 1 && embmd != null && embmd.getOwnerMember() != null && embmd.getOwnerMember().equals(mmd.getName())) { // Special case of this being a link back to the owner. TODO Repeat this for nested and their // owners ObjectProvider[] ownerOps = ec.getOwnersForEmbeddedObjectProvider(op); return (ownerOps != null && ownerOps.length > 0 ? ownerOps[0].getObject() : null); } if (relationType != RelationType.NONE && MetaDataUtils.getInstance() .isMemberEmbedded(ec.getMetaDataManager(), clr, mmd, relationType, null)) { // Embedded field if (RelationType.isRelationSingleValued(relationType)) { // TODO Cater for null value detection List<AbstractMemberMetaData> embMmds = new ArrayList<AbstractMemberMetaData>(mmds); embMmds.add(mmd); AbstractClassMetaData embCmd = ec.getMetaDataManager().getMetaDataForClass(mmd.getType(), clr); ObjectProvider embOP = ec.getNucleusContext() .getObjectProviderFactory() .newForEmbedded(ec, embCmd, op, fieldNumber); FieldManager ffm = new FetchEmbeddedFieldManager(embOP, result, embMmds, table); embOP.replaceFields(embCmd.getAllMemberPositions(), ffm); return embOP.getObject(); } } return fetchNonEmbeddedObjectField(mmd, relationType, clr); }
/** Method to add the contents of the class method. */ public void execute() { visitor.visitCode(); String fieldTypeDesc = Type.getDescriptor(fmd.getType()); Label startLabel = new Label(); visitor.visitLabel(startLabel); // "if (objPC.jdoFlags != 0 && objPC.jdoStateManager != null)" visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getFlagsFieldName(), "B"); Label l1 = new Label(); visitor.visitJumpInsn(Opcodes.IFEQ, l1); visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), "L" + getNamer().getStateManagerAsmClassName() + ";"); visitor.visitJumpInsn(Opcodes.IFNULL, l1); // "objPC.jdoStateManager.setYYYField(objPC, 8, objPC.ZZZ, val);" visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), "L" + getNamer().getStateManagerAsmClassName() + ";"); visitor.visitVarInsn(Opcodes.ALOAD, 0); EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId()); if (enhancer.getClassMetaData().getPersistenceCapableSuperclass() != null) { visitor.visitFieldInsn( Opcodes.GETSTATIC, getClassEnhancer().getASMClassName(), getNamer().getInheritedFieldCountFieldName(), "I"); visitor.visitInsn(Opcodes.IADD); } visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fmd.getName(), fieldTypeDesc); EnhanceUtils.addLoadForType(visitor, fmd.getType(), 1); String jdoMethodName = "set" + EnhanceUtils.getTypeNameForJDOMethod(fmd.getType()) + "Field"; String argTypeDesc = fieldTypeDesc; if (jdoMethodName.equals("setObjectField")) { argTypeDesc = EnhanceUtils.CD_Object; } visitor.visitMethodInsn( Opcodes.INVOKEINTERFACE, getNamer().getStateManagerAsmClassName(), jdoMethodName, "(L" + getNamer().getPersistableAsmClassName() + ";I" + argTypeDesc + argTypeDesc + ")V"); Label l3 = new Label(); visitor.visitJumpInsn(Opcodes.GOTO, l3); // "objPC.text = val;" visitor.visitLabel(l1); if (JavaUtils.useStackMapFrames()) { visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } visitor.visitVarInsn(Opcodes.ALOAD, 0); EnhanceUtils.addLoadForType(visitor, fmd.getType(), 1); visitor.visitFieldInsn( Opcodes.PUTFIELD, getClassEnhancer().getASMClassName(), fmd.getName(), fieldTypeDesc); if (enhancer.getClassMetaData().isDetachable()) { // "if (objPC.jdoIsDetached() == true) ((BitSet) objPC.jdoDetachedState[3]).set(8);" visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getIsDetachedMethodName(), "()Z"); visitor.visitJumpInsn(Opcodes.IFEQ, l3); visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getDetachedStateFieldName(), "[Ljava/lang/Object;"); visitor.visitInsn(Opcodes.ICONST_3); visitor.visitInsn(Opcodes.AALOAD); visitor.visitTypeInsn(Opcodes.CHECKCAST, "java/util/BitSet"); EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId()); if (enhancer.getClassMetaData().getPersistenceCapableSuperclass() != null) { visitor.visitFieldInsn( Opcodes.GETSTATIC, getClassEnhancer().getASMClassName(), getNamer().getInheritedFieldCountFieldName(), "I"); visitor.visitInsn(Opcodes.IADD); } visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/BitSet", "set", "(I)V"); } visitor.visitLabel(l3); if (JavaUtils.useStackMapFrames()) { visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } visitor.visitInsn(Opcodes.RETURN); Label endLabel = new Label(); visitor.visitLabel(endLabel); visitor.visitLocalVariable( argNames[0], getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0); visitor.visitLocalVariable(argNames[1], fieldTypeDesc, null, startLabel, endLabel, 1); visitor.visitMaxs(5, 2); visitor.visitEnd(); }
/** * Accessor for the expected foreign keys for this table. * * @param clr The ClassLoaderResolver * @return The expected foreign keys. */ public List getExpectedForeignKeys(ClassLoaderResolver clr) { assertIsInitialized(); boolean autoMode = false; if (storeMgr .getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_CONSTRAINT_CREATE_MODE) .equals("DataNucleus")) { autoMode = true; } ArrayList foreignKeys = new ArrayList(); try { // FK from join table to owner table DatastoreClass referencedTable = storeMgr.getDatastoreClass(ownerType, clr); if (referencedTable != null) { // Take <foreign-key> from <join> ForeignKeyMetaData fkmd = null; if (mmd.getJoinMetaData() != null) { fkmd = mmd.getJoinMetaData().getForeignKeyMetaData(); } if (fkmd != null || autoMode) { ForeignKey fk = new ForeignKey(ownerMapping, dba, referencedTable, true); fk.setForMetaData(fkmd); foreignKeys.add(fk); } } if (!isSerialisedValuePC()) { if (isEmbeddedValuePC()) { // Add any FKs for the fields of the (embedded) value EmbeddedValuePCMapping embMapping = (EmbeddedValuePCMapping) valueMapping; for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) { JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i); AbstractMemberMetaData embFmd = embFieldMapping.getMemberMetaData(); if (ClassUtils.isReferenceType(embFmd.getType()) && embFieldMapping instanceof ReferenceMapping) { // Field is a reference type, so add a FK to the table of the PC for each PC // implementation Collection fks = TableUtils.getForeignKeysForReferenceField( embFieldMapping, embFmd, autoMode, storeMgr, clr); foreignKeys.addAll(fks); } else if (storeMgr .getNucleusContext() .getMetaDataManager() .getMetaDataForClass(embFmd.getType(), clr) != null && embFieldMapping.getNumberOfDatastoreMappings() > 0 && embFieldMapping instanceof PersistableMapping) { // Field is for a PC class with the FK at this side, so add a FK to the table of this // PC ForeignKey fk = TableUtils.getForeignKeyForPCField( embFieldMapping, embFmd, autoMode, storeMgr, clr); if (fk != null) { foreignKeys.add(fk); } } } } else if (mmd.getMap().valueIsPersistent()) { // FK from join table to value table referencedTable = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr); if (referencedTable != null) { // Take <foreign-key> from <value> ForeignKeyMetaData fkmd = null; if (mmd.getValueMetaData() != null) { fkmd = mmd.getValueMetaData().getForeignKeyMetaData(); } if (fkmd != null || autoMode) { ForeignKey fk = new ForeignKey(valueMapping, dba, referencedTable, true); fk.setForMetaData(fkmd); foreignKeys.add(fk); } } } } if (!isSerialisedKeyPC()) { if (isEmbeddedKeyPC()) { // Add any FKs for the fields of the (embedded) key EmbeddedKeyPCMapping embMapping = (EmbeddedKeyPCMapping) keyMapping; for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) { JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i); AbstractMemberMetaData embFmd = embFieldMapping.getMemberMetaData(); if (ClassUtils.isReferenceType(embFmd.getType()) && embFieldMapping instanceof ReferenceMapping) { // Field is a reference type, so add a FK to the table of the PC for each PC // implementation Collection fks = TableUtils.getForeignKeysForReferenceField( embFieldMapping, embFmd, autoMode, storeMgr, clr); foreignKeys.addAll(fks); } else if (storeMgr .getNucleusContext() .getMetaDataManager() .getMetaDataForClass(embFmd.getType(), clr) != null && embFieldMapping.getNumberOfDatastoreMappings() > 0 && embFieldMapping instanceof PersistableMapping) { // Field is for a PC class with the FK at this side, so add a FK to the table of this // PC ForeignKey fk = TableUtils.getForeignKeyForPCField( embFieldMapping, embFmd, autoMode, storeMgr, clr); if (fk != null) { foreignKeys.add(fk); } } } } else if (mmd.getMap().keyIsPersistent()) { // FK from join table to key table referencedTable = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr); if (referencedTable != null) { // Take <foreign-key> from <key> ForeignKeyMetaData fkmd = null; if (mmd.getKeyMetaData() != null) { fkmd = mmd.getKeyMetaData().getForeignKeyMetaData(); } if (fkmd != null || autoMode) { ForeignKey fk = new ForeignKey(keyMapping, dba, referencedTable, true); fk.setForMetaData(fkmd); foreignKeys.add(fk); } } } } } catch (NoTableManagedException e) { // expected when no table exists } return foreignKeys; }
/** Method to add the contents of the class method. */ public void execute() { visitor.visitCode(); Label startLabel = new Label(); visitor.visitLabel(startLabel); ClassMetaData cmd = enhancer.getClassMetaData(); if (cmd.getIdentityType() == IdentityType.APPLICATION) { // application identity if (!cmd.isInstantiable()) { // Application identity but mapped-superclass with no PK defined, so throw exception visitor.visitTypeInsn( Opcodes.NEW, getClassEnhancer().getNamer().getFatalInternalExceptionAsmClassName()); visitor.visitInsn(Opcodes.DUP); visitor.visitLdcInsn("This class has no identity"); visitor.visitMethodInsn( Opcodes.INVOKESPECIAL, getClassEnhancer().getNamer().getFatalInternalExceptionAsmClassName(), "<init>", "(Ljava/lang/String;)V"); visitor.visitInsn(Opcodes.ATHROW); Label endLabel = new Label(); visitor.visitLabel(endLabel); visitor.visitLocalVariable( "this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0); visitor.visitMaxs(3, 1); } else { String objectIdClass = cmd.getObjectidClass(); int[] pkFieldNums = cmd.getPKMemberPositions(); if (enhancer .getMetaDataManager() .getApiAdapter() .isSingleFieldIdentityClass(objectIdClass)) { // SingleFieldIdentity String ACN_objectIdClass = objectIdClass.replace('.', '/'); AbstractMemberMetaData fmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[0]); visitor.visitTypeInsn(Opcodes.NEW, ACN_objectIdClass); visitor.visitInsn(Opcodes.DUP); visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); visitor.visitVarInsn(Opcodes.ALOAD, 0); if (fmd instanceof PropertyMetaData) { // Persistent property so use jdoGetXXX() visitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getGetMethodPrefixMethodName() + fmd.getName(), "()" + Type.getDescriptor(fmd.getType())); } else { // Persistent field so use xxx visitor.visitFieldInsn( Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fmd.getName(), Type.getDescriptor(fmd.getType())); } Class primitiveType = ClassUtils.getPrimitiveTypeForType(fmd.getType()); if (primitiveType != null) { // Using object wrapper of primitive so use wrapper constructor visitor.visitMethodInsn( Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "(Ljava/lang/Class;" + Type.getDescriptor(fmd.getType()) + ")V"); } else { visitor.visitMethodInsn( Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "(Ljava/lang/Class;" + getNamer().getTypeDescriptorForSingleFieldIdentityGetKey(objectIdClass) + ")V"); } visitor.visitInsn(Opcodes.ARETURN); Label endLabel = new Label(); visitor.visitLabel(endLabel); visitor.visitLocalVariable( "this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0); visitor.visitMaxs(4, 1); } else { // User-provided app identity, and compound identity String ACN_objectIdClass = objectIdClass.replace('.', '/'); visitor.visitTypeInsn(Opcodes.NEW, ACN_objectIdClass); visitor.visitInsn(Opcodes.DUP); visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "()V"); visitor.visitInsn(Opcodes.ARETURN); Label endLabel = new Label(); visitor.visitLabel(endLabel); visitor.visitLocalVariable( "this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0); visitor.visitMaxs(2, 1); } } } else { // datastore/nondurable identity visitor.visitInsn(Opcodes.ACONST_NULL); visitor.visitInsn(Opcodes.ARETURN); Label endLabel = new Label(); visitor.visitLabel(endLabel); visitor.visitLocalVariable( "this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0); visitor.visitMaxs(1, 1); } visitor.visitEnd(); }