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    }