1 18 package org.objectweb.speedo.generation.mivisitor; 19 20 import org.objectweb.speedo.metadata.SpeedoField; 21 import org.objectweb.speedo.metadata.SpeedoExtension; 22 import org.objectweb.speedo.metadata.SpeedoClass; 23 import org.objectweb.speedo.metadata.SpeedoCollection; 24 import org.objectweb.speedo.metadata.SpeedoMap; 25 import org.objectweb.speedo.metadata.SpeedoArray; 26 import org.objectweb.speedo.api.SpeedoProperties; 27 import org.objectweb.speedo.api.SpeedoException; 28 import org.objectweb.speedo.generation.enhancer.Util; 29 import org.objectweb.util.monolog.api.BasicLevel; 30 import org.objectweb.asm.Type; 31 32 38 public class ReverseFieldAdder extends AbstractMetaInfoVisitor { 39 40 public ReverseFieldAdder() { 41 } 42 43 public ReverseFieldAdder(MetaInfoVisitor mim) { 44 super(mim); 45 } 46 47 protected String getLoggerName() { 48 return LOGGER_NAME + ".reverseField"; 49 } 50 51 public void visitExtension(SpeedoExtension se) throws SpeedoException { 52 debug = logger.isLoggable(BasicLevel.DEBUG); 53 if (!SpeedoProperties.VENDOR_NAME.equals(se.vendorName) 54 || !SpeedoProperties.REVERSE_FIELD.equals(se.key)) { 55 super.visitExtension(se); 56 return; 57 } 58 59 if (!(se.jdoElement instanceof SpeedoField)) { 61 SpeedoClass sc = getSpeedoClass(se.jdoElement); 62 logger.log(BasicLevel.ERROR, "You have specified the reverse field ('" 63 + se.value + "') in other thing than a field tag ('" 64 + se.jdoElement.toString() + "')" + 65 (sc == null 66 ? "" 67 : " in class '" + sc.getFQName() + "' of the descriptor '" 68 + sc.jdoPackage.jdoXMLDescriptor.xmlFile)); 69 super.visitExtension(se); 70 return; 71 } 72 73 SpeedoField sf = (SpeedoField) se.jdoElement; 74 SpeedoField reverse = getReverseField(sf,se.value); 75 if (reverse == null) { 76 throwError("No reverse field '" + se.value + "' found for the", sf); 77 super.visitExtension(se); 78 return; 79 } 80 SpeedoExtension _se = reverse.getExtension( 81 SpeedoProperties.VENDOR_NAME, SpeedoProperties.REVERSE_FIELD); 82 if (_se == null) { 83 _se = new SpeedoExtension(SpeedoProperties.VENDOR_NAME, 85 SpeedoProperties.REVERSE_FIELD, 86 sf.name, reverse); 87 logger.log(BasicLevel.DEBUG, "add the extension(" 88 + SpeedoProperties.REVERSE_FIELD + ", " + sf.name 89 +") on the field '" + reverse.name + "'"); 90 reverse.addExtension(_se); 91 } 92 93 if (sf.jdoTuple != null) { 95 if (reverse.jdoTuple != null) { 96 sf.relationType = SpeedoField.MANY_MANY_RELATION; 97 reverse.relationType = SpeedoField.MANY_MANY_RELATION; 98 } else { 99 sf.relationType = SpeedoField.ONE_MANY_RELATION; 100 reverse.relationType = SpeedoField.MANY_ONE_RELATION; 101 } 102 } else { 103 if (reverse.jdoTuple != null) { 104 sf.relationType = SpeedoField.MANY_ONE_RELATION; 105 reverse.relationType = SpeedoField.ONE_MANY_RELATION; 106 } else { 107 sf.relationType = SpeedoField.ONE_ONE_RELATION; 108 reverse.relationType = SpeedoField.ONE_ONE_RELATION; 109 } 110 } 111 112 checkExtension(sf, se, reverse, 113 SpeedoProperties.TARGET_FK, SpeedoProperties.SOURCE_FK); 114 checkExtension(sf, se, reverse, 115 SpeedoProperties.SOURCE_FK, SpeedoProperties.TARGET_FK); 116 checkExtension(sf, se, reverse, 117 SpeedoProperties.JOIN_TABLE, SpeedoProperties.JOIN_TABLE); 118 super.visitExtension(se); 119 } 120 121 133 private SpeedoExtension checkExtension(SpeedoField sf, 134 SpeedoExtension se, 135 SpeedoField reverse, 136 String ext1, 137 String ext2) throws SpeedoException { 138 SpeedoExtension _se = sf.getExtension(SpeedoProperties.VENDOR_NAME, ext1); 139 if (_se != null) { 140 SpeedoExtension __se = reverse.getExtension(SpeedoProperties.VENDOR_NAME, ext2); 141 if (__se == null) { 142 __se = new SpeedoExtension(SpeedoProperties.VENDOR_NAME, ext2, _se.value, reverse); 144 logger.log(BasicLevel.DEBUG, "add the extension(" + ext2 145 + ", " + _se.value +") on the field '" 146 + reverse.name + "'"); 147 reverse.addExtension(__se); 148 } else if (!__se.value.equals(_se.value)) { 149 throwError("A bad mapping has been specified on the reverse field '" 150 + se.value + "' for the ", sf); 151 super.visitExtension(se); 152 return _se; 153 } else if (debug) { 154 SpeedoClass sc1 = getSpeedoClass(sf); 155 SpeedoClass sc2 = getSpeedoClass(reverse); 156 logger.log(BasicLevel.DEBUG, "You could remove one of the following extensions:" 157 + "\n- .jdo: '" + sc1.jdoPackage.jdoXMLDescriptor.xmlFile 158 + "', class: '" + sc1.getFQName() 159 + "', field: '" + sf.name 160 + "', extension: '" + ext1 + "'" 161 162 + "\n- .jdo: '" + sc2.jdoPackage.jdoXMLDescriptor.xmlFile 163 + "', class: '" + sc2.getFQName() 164 + "', field: '" + reverse.name 165 + "', extension: '" + ext2 + "'" 166 ); 167 } 168 } 169 return _se; 170 } 171 172 178 public static SpeedoField getReverseField(SpeedoField sf, String rfn) throws SpeedoException { 179 String className = null; 180 if (sf.jdoTuple != null) { 181 if (sf.jdoTuple instanceof SpeedoCollection) { 182 className = (String ) ((SpeedoCollection) sf.jdoTuple).elementType; 183 } else if (sf.jdoTuple instanceof SpeedoMap) { 184 className = (String ) ((SpeedoMap) sf.jdoTuple).valueType; 185 } else if (sf.jdoTuple instanceof SpeedoArray) { 186 className = Util.type(Type.getType(sf.desc)); 187 } 188 } else { 189 className = Util.type(Type.getType(sf.desc)); 190 } 191 SpeedoClass sc = sf.jdoClass.jdoPackage 192 .jdoXMLDescriptor.getSpeedoClass(className, true); 193 if (sc == null) { 194 sc = sf.jdoClass.jdoPackage.jdoXMLDescriptor.getSpeedoClass( 195 getSpeedoClass(sf).jdoPackage.name + "." + className, true); 196 } 197 if (sc == null) { 198 throwError("No persistent class '" + className + "' found for managing the ", sf); 199 return null; 200 } 201 return (SpeedoField) sc.jdoField.get(rfn); 202 } 203 204 209 public static void throwError(String msg, SpeedoField sf) throws SpeedoException { 210 throw new SpeedoException(msg + " field '" + sf.name 211 + "' of the class '" + sf.jdoClass.getFQName() 212 + "' in the descriptor '" 213 + sf.jdoClass.jdoPackage.jdoXMLDescriptor.xmlFile + "'"); 214 } 215 216 217 } 218 | Popular Tags |