001    package edu.rice.cs.cunit.threadCheck.predicates;
002    
003    import java.lang.reflect.Field;
004    
005    /**
006     * Class containing several common predicates that use reflection.
007     * @author Mathias Ricken
008     */
009    public class ReflectionThreadCheckPredicates {
010        /**
011         * Return true if the current thread is equal to the thread in the specified field.
012         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
013         * @param fieldClass the class the field is in
014         * @param fieldName the name of the field
015         * @return true if the current thread is equal to the thread in the specified field
016         */
017        public static boolean checkThread(Object thisObject, Class fieldClass, String fieldName) {
018            try {
019                Field field = fieldClass.getDeclaredField(fieldName);
020                boolean isAccessible = field.isAccessible();
021                field.setAccessible(true);
022                Object value = field.get(thisObject);
023                field.setAccessible(isAccessible);
024                if (value instanceof Thread) {
025                    return (Thread.currentThread()==value);
026                }
027            }
028            catch(Exception e) {
029                e.printStackTrace();
030            }
031            return false;
032        }
033    
034        /**
035         * Return true if the current thread's name is equal to the string in the specified field.
036         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
037         * @param fieldClass the class the field is in
038         * @param fieldName the name of the field
039         * @return true if the current thread's name is equal to the string in the specified field
040         */
041        public static boolean checkName(Object thisObject, Class fieldClass, String fieldName) {
042            try {
043                Field field = fieldClass.getDeclaredField(fieldName);
044                boolean isAccessible = field.isAccessible();
045                field.setAccessible(true);
046                Object value = field.get(thisObject);
047                field.setAccessible(isAccessible);
048                if (value instanceof String) {
049                    return (Thread.currentThread().getName().equals(value));
050                }
051            }
052            catch(Exception e) {
053                e.printStackTrace();
054            }
055            return false;
056        }
057    
058        /**
059         * Return true if the current thread's group name is equal to the string in the specified field.
060         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
061         * @param fieldClass the class the field is in
062         * @param fieldName the name of the field
063         * @return true if the current thread's group name is equal to the string in the specified field
064         */
065        public static boolean checkGroup(Object thisObject, Class fieldClass, String fieldName) {
066            try {
067                Field field = fieldClass.getDeclaredField(fieldName);
068                boolean isAccessible = field.isAccessible();
069                field.setAccessible(true);
070                Object value = field.get(thisObject);
071                field.setAccessible(isAccessible);
072                if (value instanceof String) {
073                    return (Thread.currentThread().getThreadGroup().getName().equals(value));
074                }
075            }
076            catch(Exception e) {
077                e.printStackTrace();
078            }
079            return false;
080        }
081    
082        /**
083         * Return true if the current thread is equal to the thread in the specified field.
084         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
085         * @param fieldClassName the name of the class the field is in
086         * @param fieldName the name of the field
087         * @return true if the current thread is equal to the thread in the specified field
088         */
089        public static boolean checkThreadByName(Object thisObject, String fieldClassName, String fieldName) {
090            try {
091                return checkThread(thisObject, Class.forName(fieldClassName), fieldName);
092            }
093            catch(Exception e) {
094                e.printStackTrace();
095            }
096            return false;
097        }
098    
099        /**
100         * Return true if the current thread's name is equal to the string in the specified field.
101         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
102         * @param fieldClassName the name of the class the field is in
103         * @param fieldName the name of the field
104         * @return true if the current thread's name is equal to the string in the specified field
105         */
106        public static boolean checkNameByName(Object thisObject, String fieldClassName, String fieldName) {
107            try {
108                return checkName(thisObject, Class.forName(fieldClassName), fieldName);
109            }
110            catch(Exception e) {
111                e.printStackTrace();
112            }
113            return false;
114        }
115    
116        /**
117         * Return true if the current thread's group name is equal to the string in the specified field.
118         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
119         * @param fieldClassName the name of the class the field is in
120         * @param fieldName the name of the field
121         * @return true if the current thread's group name is equal to the string in the specified field
122         */
123        public static boolean checkGroupByName(Object thisObject, String fieldClassName, String fieldName) {
124            try {
125                return checkGroup(thisObject, Class.forName(fieldClassName), fieldName);
126            }
127            catch(Exception e) {
128                e.printStackTrace();
129            }
130            return false;
131        }
132    
133        /**
134         * Return true if the current thread owns the monitor of the specified field.
135         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
136         * @param fieldClass the class the field is in
137         * @param fieldName the name of the field
138         * @return true if the current thread owns the monitor of the specified field
139         */
140        public static boolean checkSynchronizedField(Object thisObject, Class fieldClass, String fieldName) {
141            try {
142                Field field = fieldClass.getDeclaredField(fieldName);
143                boolean isAccessible = field.isAccessible();
144                field.setAccessible(true);
145                Object value = field.get(thisObject);
146                field.setAccessible(isAccessible);
147                return ThreadCheckPredicates.checkMonitorOwned(value);
148            }
149            catch(Exception e) {
150                e.printStackTrace();
151            }
152            return false;
153        }
154    
155        /**
156         * Return true if the current thread owns the monitor of the specified field.
157         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
158         * @param fieldClassName the name of the class the field is in
159         * @param fieldName the name of the field
160         * @return true if the current thread owns the monitor of the specified field
161         */
162        public static boolean checkSynchronizedFieldByName(Object thisObject, String fieldClassName, String fieldName) {
163            try {
164                return checkSynchronizedField(thisObject, Class.forName(fieldClassName), fieldName);
165            }
166            catch(Exception e) {
167                e.printStackTrace();
168            }
169            return false;
170        }
171        
172        /**
173         * Return true if the any thread owns the monitor of the specified field.
174         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
175         * @param fieldClass the class the field is in
176         * @param fieldName the name of the field
177         * @return true if the any thread owns the monitor of the specified field
178         */
179        public static boolean checkSynchronizedFieldByAnyThread(Object thisObject, Class fieldClass, String fieldName) {
180            try {
181                Field field = fieldClass.getDeclaredField(fieldName);
182                boolean isAccessible = field.isAccessible();
183                field.setAccessible(true);
184                Object value = field.get(thisObject);
185                field.setAccessible(isAccessible);
186                return ThreadCheckPredicates.checkMonitorOwnedByAnyThread(value);
187            }
188            catch(Exception e) {
189                e.printStackTrace();
190            }
191            return false;
192        }
193    
194        /**
195         * Return true if any thread owns the monitor of the specified field.
196         * @param thisObject "this" at the time of the check, or null if not available; ignored by this method
197         * @param fieldClassName the name of the class the field is in
198         * @param fieldName the name of the field
199         * @return true if any thread owns the monitor of the specified field
200         */
201        public static boolean checkSynchronizedFieldByAnyThreadByName(Object thisObject, String fieldClassName, String fieldName) {
202            try {
203                return checkSynchronizedFieldByAnyThread(thisObject, Class.forName(fieldClassName), fieldName);
204            }
205            catch(Exception e) {
206                e.printStackTrace();
207            }
208            return false;
209        }
210    }