001 /* 002 Copyright (C) 2002 Julien van Malderen, Renaud Pawlak <renaud@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.aspects.integrity; 019 020 import java.util.Iterator; 021 import java.util.Vector; 022 import org.aopalliance.intercept.ConstructorInvocation; 023 import org.aopalliance.intercept.MethodInvocation; 024 import org.apache.log4j.Logger; 025 import org.objectweb.jac.core.AspectComponent; 026 import org.objectweb.jac.core.Interaction; 027 import org.objectweb.jac.core.Wrapper; 028 import org.objectweb.jac.core.rtti.ClassItem; 029 import org.objectweb.jac.core.rtti.ClassRepository; 030 import org.objectweb.jac.core.rtti.FieldItem; 031 import org.objectweb.jac.core.rtti.MethodItem; 032 033 /** 034 * This wrapper provides a constraints scheme to limit fields 035 * modifications. 036 */ 037 038 public class ConstraintWrapper extends Wrapper { 039 static final Logger logger = Logger.getLogger("integrity.conditions"); 040 041 public ConstraintWrapper(AspectComponent ac) { 042 super(ac); 043 } 044 045 private void invokeTest( 046 MethodItem method, 047 FieldItem field, 048 Object[] args, 049 String errorMsg) 050 throws Exception 051 { 052 Boolean result = (Boolean) method.invoke(null, args); 053 054 if (result == null) 055 throw new Exception("The constraint " + method + " does not exist"); 056 057 if (!result.booleanValue()) { 058 if ((errorMsg == null) || errorMsg.length() == 0) 059 throw new Exception( 060 "The constraint " 061 + method 062 + " has not been validated for " 063 + field); 064 throw new Exception(field + ": " + errorMsg); 065 } 066 } 067 068 /** 069 * This wrapping method checks if pre and post conditions are 070 * validated for modified fields. 071 */ 072 073 public Object testConditions(Interaction interaction) throws Exception { 074 logger.debug( 075 "entering test conditions for " + interaction.method); 076 077 IntegrityAC ac = (IntegrityAC) getAspectComponent(); 078 String fieldName = 079 ((MethodItem) interaction.method).getWrittenFields()[0].getName(); 080 ClassItem curClass = 081 ClassRepository.get().getClass(interaction.wrappee); 082 FieldItem field = null; 083 Vector preList = null; 084 085 // get the pre list from the superclasses if not defined here 086 while (preList == null && curClass != null) { 087 field = curClass.getField(fieldName); 088 preList = (Vector) ac.preConditionsFields.get(field); 089 logger.debug( 090 field.getClassItem() + "." + field + " => " + preList); 091 curClass = curClass.getSuperclass(); 092 } 093 094 Vector postList = null; 095 curClass = ClassRepository.get().getClass(interaction.wrappee); 096 097 // get the post list from the superclasses if not defined here 098 while (postList == null && curClass != null) { 099 field = curClass.getField(fieldName); 100 postList = (Vector) ac.postConditionsFields.get(field); 101 logger.debug( 102 field.getClassItem() + "." + field + " => " + preList); 103 curClass = curClass.getSuperclass(); 104 } 105 106 if (preList != null) { 107 Iterator i = preList.iterator(); 108 Object currentFieldValue = 109 field.getThroughAccessor(interaction.wrappee); 110 while (i.hasNext()) { 111 ConstraintDescriptor conditionToTest = 112 (ConstraintDescriptor) i.next(); 113 logger.debug( 114 "testing pre " + conditionToTest.getConstraint()); 115 invokeTest( 116 conditionToTest.getConstraint(), 117 field, 118 new Object[] { 119 interaction.wrappee, 120 field, 121 currentFieldValue, 122 conditionToTest.getParams()}, 123 conditionToTest.getErrorMsg()); 124 } 125 } 126 127 if (postList != null) { 128 Iterator i = postList.iterator(); 129 while (i.hasNext()) { 130 ConstraintDescriptor conditionToTest = 131 (ConstraintDescriptor) i.next(); 132 logger.debug( 133 "testing post " + conditionToTest.getConstraint()); 134 invokeTest( 135 conditionToTest.getConstraint(), 136 field, 137 new Object[] { 138 interaction.wrappee, 139 field, 140 interaction.args[0], 141 conditionToTest.getParams()}, 142 conditionToTest.getErrorMsg()); 143 } 144 } 145 146 return proceed(interaction); 147 } 148 149 public Object invoke(MethodInvocation invocation) throws Throwable { 150 return testConditions((Interaction) invocation); 151 } 152 }