001 package org.apache.ojb.broker.metadata.fieldaccess;
002
003 /* Copyright 2003-2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 import java.io.Serializable;
019 import java.lang.reflect.Field;
020 import java.security.AccessController;
021 import java.security.PrivilegedAction;
022
023 /**
024 * A {@link PersistentField} implementation using
025 * reflection to access but does cooperate with
026 * AccessController and do not suppress the java
027 * language access check.
028 *
029 * @version $Id: PersistentFieldPrivilegedImpl.java,v 1.1 2007-08-24 22:17:35 ewestfal Exp $
030 * @see PersistentFieldDirectImpl
031 */
032 public class PersistentFieldPrivilegedImpl extends PersistentFieldDirectImpl
033 {
034 private static final long serialVersionUID = -6110158693763128846L;
035
036 private SetAccessibleAction setAccessibleAction = new SetAccessibleAction();
037 private UnsetAccessibleAction unsetAccessibleAction = new UnsetAccessibleAction();
038 private static final int ACCESSIBLE_STATE_UNKOWN = 0;
039 private static final int ACCESSIBLE_STATE_FALSE = 1;
040 private static final int ACCESSIBLE_STATE_SET_TRUE = 2;
041
042 public PersistentFieldPrivilegedImpl()
043 {
044 }
045
046 public PersistentFieldPrivilegedImpl(Class type, String fieldname)
047 {
048 super(type, fieldname);
049 }
050
051 protected Object getValueFrom(Field field, Object target)
052 {
053 int accessibleState = ACCESSIBLE_STATE_UNKOWN;
054 Object result = null;
055 if (!field.isAccessible()) accessibleState = ACCESSIBLE_STATE_FALSE;
056 if (accessibleState == ACCESSIBLE_STATE_FALSE)
057 {
058 accessibleState = ACCESSIBLE_STATE_SET_TRUE;
059 setAccessibleAction.current = field;
060 AccessController.doPrivileged(setAccessibleAction);
061 }
062 try
063 {
064 result = super.getValueFrom(field, target);
065 }
066 finally
067 {
068 if (accessibleState == ACCESSIBLE_STATE_SET_TRUE)
069 {
070 unsetAccessibleAction.current = field;
071 AccessController.doPrivileged(unsetAccessibleAction);
072 }
073 }
074 return result;
075 }
076
077 protected void setValueFor(Field field, Object target, Object value)
078 {
079 int accessibleState = ACCESSIBLE_STATE_UNKOWN;
080 if (!field.isAccessible()) accessibleState = ACCESSIBLE_STATE_FALSE;
081 if (accessibleState == ACCESSIBLE_STATE_FALSE)
082 {
083 accessibleState = ACCESSIBLE_STATE_SET_TRUE;
084 setAccessibleAction.current = field;
085 AccessController.doPrivileged(setAccessibleAction);
086 }
087 try
088 {
089 super.setValueFor(field, target, value);
090 }
091 finally
092 {
093 if (accessibleState == ACCESSIBLE_STATE_SET_TRUE)
094 {
095 unsetAccessibleAction.current = field;
096 AccessController.doPrivileged(unsetAccessibleAction);
097 }
098 }
099 }
100
101 /**
102 * This implementation returns always 'false'.
103 */
104 public boolean makeAccessible()
105 {
106 return false;
107 }
108
109 /**
110 * Always returns 'false'.
111 *
112 * @see PersistentField#usesAccessorsAndMutators
113 */
114 public boolean usesAccessorsAndMutators()
115 {
116 return false;
117 }
118
119 //************************************************************
120 // inner class
121 //************************************************************
122 private static class SetAccessibleAction implements PrivilegedAction, Serializable
123 {
124 static final long serialVersionUID = 8152025069698028050L;
125 transient Field current;
126
127 public Object run()
128 {
129 current.setAccessible(true);
130 return null;
131 }
132 }
133
134 private static class UnsetAccessibleAction implements PrivilegedAction, Serializable
135 {
136 static final long serialVersionUID = -2284913657454430305L;
137 transient Field current;
138
139 public Object run()
140 {
141 current.setAccessible(false);
142 return null;
143 }
144 }
145 }