1 17 18 package org.objectweb.jac.aspects.integrity; 19 20 import org.aopalliance.intercept.ConstructorInvocation; 21 import org.aopalliance.intercept.MethodInvocation; 22 import org.apache.log4j.Logger; 23 import org.objectweb.jac.core.AspectComponent; 24 import org.objectweb.jac.core.Collaboration; 25 import org.objectweb.jac.core.Interaction; 26 import org.objectweb.jac.core.Wrapper; 27 import org.objectweb.jac.core.rtti.ClassItem; 28 import org.objectweb.jac.core.rtti.CollectionItem; 29 import org.objectweb.jac.core.rtti.FieldItem; 30 import org.objectweb.jac.core.rtti.MethodItem; 31 import org.objectweb.jac.core.rtti.RttiAC; 32 33 36 37 public class RoleWrapper extends Wrapper { 38 static final Logger logger = Logger.getLogger("integrity"); 39 40 public RoleWrapper(AspectComponent ac) { 41 super(ac); 42 } 43 44 48 public Object updateOppositeRole(Interaction interaction) { 49 logger.debug("updateOppositeRoles " + interaction.method + "..."); 50 if (attr("rtti.updateOpposite") != null || 51 attr(IntegrityAC.DISABLE_ROLE_UPDATES)!=null) 52 return interaction.proceed(); 53 54 doUpdate(interaction); 55 56 Object result = interaction.proceed(); 57 return result; 58 } 59 60 protected void doUpdate(Interaction interaction) { 61 logger.debug( 62 "updateOppositeRoles "+interaction.wrappee+"."+ 63 interaction.method+"("+interaction.args[0]+")"); 64 ClassItem cli = interaction.getClassItem(); 65 MethodItem method = (MethodItem) interaction.method; 66 67 FieldItem[] fields = method.getWrittenFields(); 69 FieldItem opposite; 70 Object newValue = interaction.args[0]; 71 for (int i = 0; fields != null && i < fields.length; i++) { 72 FieldItem field = fields[i]; 73 Object currentValue = field.getThroughAccessor(interaction.wrappee); 74 opposite = (FieldItem) field.getAttribute(RttiAC.OPPOSITE_ROLE); 75 if (opposite != null) { 76 try { 77 attrdef("rtti.updateOpposite", opposite); 78 logger.debug( 79 "UpdateOppositeRole in "+interaction.method+" : "+ 80 fields[i].getName()+" -> "+opposite.getName()); 81 logger.debug( 82 "wrappee = "+interaction.wrappee+" ; "+ 83 "currentValue = "+currentValue); 84 if (opposite instanceof CollectionItem) { 85 CollectionItem oppositeCollection = 86 (CollectionItem) opposite; 87 if (currentValue != null) 88 oppositeCollection.removeThroughRemover( 89 currentValue, 90 interaction.wrappee); 91 if (newValue != null 92 && !oppositeCollection.contains( 93 newValue, 94 interaction.wrappee)) 95 oppositeCollection.addThroughAdder( 96 newValue, 97 interaction.wrappee); 98 } else { 99 if (currentValue != null) { 100 opposite.setThroughWriter(currentValue, null); 101 } 102 if (newValue!=null) 103 opposite.setThroughWriter( 104 newValue, 105 interaction.wrappee); 106 } 107 } catch (Exception e) { 108 logger.error( 109 "Failed to update opposite role "+opposite.getLongName()+" of "+ 110 field.getLongName()+" on "+interaction.wrappee,e); 111 } finally { 112 attrdef("rtti.updateOpposite", null); 113 } 114 } 115 } 116 117 CollectionItem[] collections = method.getAddedCollections(); 119 Object addedValue = interaction.args[0]; 120 for (int i = 0; collections != null && i < collections.length; i++) { 121 CollectionItem collection = collections[i]; 122 opposite = 123 (FieldItem) collection.getAttribute(RttiAC.OPPOSITE_ROLE); 124 if (opposite == null) { 125 logger.debug( 126 collection.getParent().getName()+"."+collection.toString()+ 127 " has no opposite role"); 128 continue; 129 } 130 logger.debug( 131 "UpdateOppositeRole #"+i+" in "+interaction.method+" : "+ 132 collection.getName()+" -> "+opposite.getName()); 133 try { 134 attrdef("rtti.updateOpposite", opposite); 135 if (opposite instanceof CollectionItem) { 136 CollectionItem oppositeCollection = 137 (CollectionItem) opposite; 138 if (addedValue != null 139 && !oppositeCollection.contains( 140 addedValue, 141 interaction.wrappee)) 142 oppositeCollection.addThroughAdder( 143 addedValue, 144 interaction.wrappee); 145 } else { 146 if (addedValue != null) { 147 Object currentValue = opposite.get(addedValue); 148 logger.debug(" currentValue="+currentValue+ 149 ", interaction.wrappee="+interaction.wrappee); 150 if (currentValue != null && 151 currentValue != interaction.wrappee) { 152 collection.removeThroughRemover( 153 currentValue, 154 addedValue); 155 } 156 opposite.setThroughWriter( 157 addedValue, 158 interaction.wrappee); 159 } 160 } 161 } catch (Exception e) { 162 logger.error( 163 "Failed to update opposite role "+opposite.getLongName()+" of "+ 164 collection.getLongName()+" on "+interaction.wrappee,e); 165 } finally { 166 attrdef("rtti.updateOpposite", null); 167 } 168 } 169 170 collections = method.getRemovedCollections(); 172 Object removedValue = interaction.args[0]; 173 for (int i = 0; collections != null && i < collections.length; i++) { 174 CollectionItem collection = collections[i]; 175 logger.debug("removed collection " + collection); 176 opposite = 177 (FieldItem) collection.getAttribute(RttiAC.OPPOSITE_ROLE); 178 try { 179 attrdef("rtti.updateOpposite", opposite); 180 if (opposite == null) { 181 logger.debug( 182 collection.getParent().getName()+"."+collection.toString()+ 183 " has no opposite role"); 184 continue; 185 } 186 logger.debug( 187 "UpdateOppositeRole in "+interaction.method+" : "+collection.getName()+ 188 " -> "+opposite.getName()); 189 if (removedValue != null) { 190 if (opposite instanceof CollectionItem) { 191 ((CollectionItem) opposite).removeThroughRemover( 192 removedValue, 193 interaction.wrappee); 194 } else { 195 opposite.setThroughWriter(removedValue, null); 196 } 197 } 198 } catch (Exception e) { 199 logger.error("Failed to update opposite role "+opposite.getLongName()+" of " 200 +collection.getLongName()+" on "+interaction.wrappee,e); 201 } finally { 202 attrdef("rtti.updateOpposite", null); 203 } 204 205 } 206 } 207 208 213 public Object initAutoCreatedObject(Interaction interaction) { 214 Object result = interaction.proceed(); 215 Collaboration collab = Collaboration.get(); 216 Interaction reason = 217 (Interaction) collab.getAttribute("GuiAC.AUTOCREATE_REASON"); 218 if (reason != null) { 219 logger.debug( 220 "initAutoCreatedObject for " 221 + interaction + " because of " + reason); 222 reason.args[0] = interaction.wrappee; 223 collab.removeAttribute("GuiAC.AUTOCREATE_REASON"); 227 doUpdate(reason); 228 } 229 return result; 230 } 231 232 236 public static void disableRoleUpdate(FieldItem role) { 237 Collaboration.get().addAttribute("rtti.updateOpposite", role); 238 } 239 240 public static void enableRoleUpdate(FieldItem role) { 241 Collaboration.get().removeAttribute("rtti.updateOpposite"); 242 } 243 244 public Object invoke(MethodInvocation invocation) throws Throwable { 245 return this.updateOppositeRole((Interaction) invocation); 246 } 247 248 public Object construct(ConstructorInvocation invocation) 249 throws Throwable 250 { 251 return this.initAutoCreatedObject((Interaction) invocation); 252 } 253 } 254 | Popular Tags |