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 */
017package org.apache.commons.jxpath.ri.model;
018
019import java.util.Locale;
020
021import org.apache.commons.jxpath.JXPathContext;
022import org.apache.commons.jxpath.Variables;
023import org.apache.commons.jxpath.ri.QName;
024
025/**
026 * NodePointerFactory to create {@link VariablePointer VariablePointers}.
027 * @author Matt Benson
028 * @since JXPath 1.3
029 * @version $Revision: 652845 $ $Date: 2008-05-02 13:46:46 -0400 (Fri, 02 May 2008) $
030 */
031public class VariablePointerFactory implements NodePointerFactory {
032    /** factory order constant */
033    public static final int VARIABLE_POINTER_FACTORY_ORDER = 890;
034
035    /**
036     * Node value wrapper to trigger a VariablePointerFactory.
037     */
038    public static final class VariableContextWrapper {
039        private final JXPathContext context;
040
041        /**
042         * Create a new VariableContextWrapper.
043         * @param context to wrap
044         */
045        private VariableContextWrapper(JXPathContext context) {
046            this.context = context;
047        }
048
049        /**
050         * Get the original (unwrapped) context.
051         *
052         * @return JXPathContext.
053         */
054        public JXPathContext getContext() {
055            return context;
056        }
057    }
058
059    /**
060     * VariableContextWrapper factory method.
061     * @param context the JXPathContext to wrap.
062     * @return VariableContextWrapper.
063     */
064    public static VariableContextWrapper contextWrapper(JXPathContext context) {
065        return new VariableContextWrapper(context);
066    }
067
068    public NodePointer createNodePointer(QName name, Object object,
069            Locale locale) {
070        if (object instanceof VariableContextWrapper) {
071            JXPathContext varCtx = ((VariableContextWrapper) object).getContext();
072            while (varCtx != null) {
073                Variables vars = varCtx.getVariables();
074                if (vars.isDeclaredVariable(name.toString())) {
075                    return new VariablePointer(vars, name);
076                }
077                varCtx = varCtx.getParentContext();
078            }
079            // The variable is not declared, but we will create
080            // a pointer anyway in case the user wants to set, rather
081            // than get, the value of the variable.
082            return new VariablePointer(name);
083        }
084        return null;
085    }
086
087    public NodePointer createNodePointer(NodePointer parent, QName name,
088            Object object) {
089        return createNodePointer(name, object, null);
090    }
091
092    public int getOrder() {
093        return VARIABLE_POINTER_FACTORY_ORDER;
094    }
095
096}