    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
    018package org.apache.commons.jxpath.ri.model.dynabeans;
    019
    020import java.util.Locale;
    021
    022import org.apache.commons.beanutils.LazyDynaBean;
    023import org.apache.commons.beanutils.LazyDynaClass;
    024import org.apache.commons.jxpath.ri.QName;
    025import org.apache.commons.jxpath.ri.model.NodePointer;
    026import org.apache.commons.jxpath.ri.model.NodePointerFactory;
    027import org.apache.commons.jxpath.ri.model.beans.PropertyPointer;
    028
    029/**
    030 * Implemented in response to [JXPATH-144]. Optionally pluggable {@code NodePointerFactory} that returns a special type of {@code NodePointer} for
    031 * {@code LazyDynaBean}s. The {@code PropertyPointer}s returned by these will respect {@link LazyDynaClass#isDynaProperty(String)} when determining
    032 * {@link PropertyPointer#isActual()}.
    033 *
    034 * @since 1.4.0
    035 */
    036public class StrictLazyDynaBeanPointerFactory implements NodePointerFactory {
    037
    038    /**
    039     * Pointer implementation.
    040     */
    041    private static final class StrictLazyDynaBeanPointer extends DynaBeanPointer {
    042
    043        private static final long serialVersionUID = 1L;
    044        private final LazyDynaBean lazyDynaBean;
    045
    046        /**
    047         * Constructs a new StrictLazyDynaBeanPointer instance.
    048         *
    049         * @param parent       pointer
    050         * @param qName        is the name given to the first node
    051         * @param lazyDynaBean pointed
    052         */
    053        public StrictLazyDynaBeanPointer(final NodePointer parent, final QName qName, final LazyDynaBean lazyDynaBean) {
    054            super(parent, qName, lazyDynaBean);
    055            this.lazyDynaBean = lazyDynaBean;
    056        }
    057
    058        /**
    059         * Constructs a new StrictLazyDynaBeanPointer instance.
    060         *
    061         * @param qName        is the name given to the first node
    062         * @param lazyDynaBean pointed
    063         * @param locale       Locale
    064         */
    065        public StrictLazyDynaBeanPointer(final QName qName, final LazyDynaBean lazyDynaBean, final Locale locale) {
    066            super(qName, lazyDynaBean, locale);
    067            this.lazyDynaBean = lazyDynaBean;
    068        }
    069
    070        /**
    071         * {@inheritDoc}
    072         */
    073        @Override
    074        public PropertyPointer getPropertyPointer() {
    075            return new DynaBeanPropertyPointer(this, lazyDynaBean) {
    076
    077                private static final long serialVersionUID = 1L;
    078
    079                @Override
    080                protected boolean isActualProperty() {
    081                    return ((LazyDynaClass) lazyDynaBean.getDynaClass()).isDynaProperty(getPropertyName());
    082                }
    083            };
    084        }
    085    }
    086
    087    /**
    088     * Constructs a new instance.
    089     */
    090    public StrictLazyDynaBeanPointerFactory() {
    091        // empty
    092    }
    093
    094    /**
    095     * {@inheritDoc}
    096     */
    097    @Override
    098    public NodePointer createNodePointer(final NodePointer parent, final QName qName, final Object object) {
    099        return object instanceof LazyDynaBean ? new StrictLazyDynaBeanPointer(parent, qName, (LazyDynaBean) object) : null;
    100    }
    101
    102    /**
    103     * {@inheritDoc}
    104     */
    105    @Override
    106    public NodePointer createNodePointer(final QName qName, final Object object, final Locale locale) {
    107        return object instanceof LazyDynaBean ? new StrictLazyDynaBeanPointer(qName, (LazyDynaBean) object, locale) : null;
    108    }
    109
    110    /**
    111     * {@inheritDoc}
    112     */
    113    @Override
    114    public int getOrder() {
    115        return DynaBeanPointerFactory.DYNA_BEAN_POINTER_FACTORY_ORDER - 1;
    116    }
    117}