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}