    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  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    package org.apache.commons.jexl2.introspection;
    018
    019    import org.apache.commons.jexl2.JexlInfo;
    020    import org.apache.commons.logging.Log;
    021
    022    /**
    023     * An uberspect that controls usage of properties, methods and contructors through a sandbox.
    024     * @since 2.1
    025     */
    026    public class SandboxUberspectImpl extends UberspectImpl {
    027        /**  The sandbox. */
    028        protected final Sandbox sandbox;
    029
    030        /**
    031         * A constructor for Sandbox uberspect.
    032         * @param runtimeLogger the logger to use or null to use default
    033         * @param theSandbox the sandbox instance to use
    034         */
    035        public SandboxUberspectImpl(Log runtimeLogger, Sandbox theSandbox) {
    036            super(runtimeLogger);
    037            if (theSandbox == null) {
    038                throw new NullPointerException("sandbox can not be null");
    039            }
    040            this.sandbox = theSandbox;
    041        }
    042
    043        /**
    044         * {@inheritDoc}
    045         */
    046        @Override
    047        public void setLoader(ClassLoader cloader) {
    048            base().setLoader(cloader);
    049        }
    050
    051        /**
    052         * {@inheritDoc}
    053         */
    054        @Override
    055        public JexlMethod getConstructorMethod(Object ctorHandle, Object[] args, JexlInfo info) {
    056            final String className;
    057            if (ctorHandle instanceof Class<?>) {
    058                Class<?> clazz = (Class<?>) ctorHandle;
    059                className = clazz.getName();
    060            } else if (ctorHandle != null) {
    061                className = ctorHandle.toString();
    062            } else {
    063                return null;
    064            }
    065            if (sandbox.execute(className, "") != null) {
    066                return super.getConstructorMethod(className, args, info);
    067            }
    068            return null;
    069        }
    070
    071        /**
    072         * {@inheritDoc}
    073         */
    074        @Override
    075        public JexlMethod getMethod(Object obj, String method, Object[] args, JexlInfo info) {
    076            if (obj != null && method != null) {
    077                String actual = sandbox.execute(obj.getClass().getName(), method);
    078                if (actual != null) {
    079                    return getMethodExecutor(obj, actual, args);
    080                }
    081            }
    082            return null;
    083        }
    084
    085        /**
    086         * {@inheritDoc}
    087         */
    088        @Override
    089        public JexlPropertyGet getPropertyGet(Object obj, Object identifier, JexlInfo info) {
    090            if (obj != null && identifier != null) {
    091                String actual = sandbox.read(obj.getClass().getName(), identifier.toString());
    092                if (actual != null) {
    093                    return super.getPropertyGet(obj, actual, info);
    094                }
    095            }
    096            return null;
    097        }
    098
    099        /**
    100         * {@inheritDoc}
    101         */
    102        @Override
    103        public JexlPropertySet getPropertySet(final Object obj, final Object identifier, Object arg, JexlInfo info) {
    104            if (obj != null && identifier != null) {
    105                String actual = sandbox.write(obj.getClass().getName(), identifier.toString());
    106                if (actual != null) {
    107                    return super.getPropertySet(obj, actual, arg, info);
    108                }
    109            }
    110            return null;
    111
    112        }
    113    }