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.compiler;
019
020import org.apache.commons.jxpath.ri.EvalContext;
021import org.apache.commons.jxpath.ri.axes.InitialContext;
022
023/**
024 * A location path expression.
025 */
026public class LocationPath extends Path {
027
028    private final boolean absolute;
029
030    /**
031     * Constructs a new LocationPath.
032     *
033     * @param absolute whether this is an absolute path
034     * @param steps    to evaluate
035     */
036    public LocationPath(final boolean absolute, final Step[] steps) {
037        super(steps);
038        this.absolute = absolute;
039    }
040
041    @Override
042    public Object compute(final EvalContext context) {
043        // Create a chain of contexts
044        EvalContext rootContext;
045        if (isAbsolute()) {
046            rootContext = context.getRootContext().getAbsoluteRootContext();
047        } else {
048            rootContext = new InitialContext(context);
049        }
050        return evalSteps(rootContext);
051    }
052
053    @Override
054    public boolean computeContextDependent() {
055        return !absolute || super.computeContextDependent();
056    }
057
058    @Override
059    public Object computeValue(final EvalContext context) {
060        // Create a chain of contexts
061        EvalContext rootContext;
062        if (isAbsolute()) {
063            rootContext = context.getRootContext().getAbsoluteRootContext();
064        } else {
065            rootContext = new InitialContext(context);
066        }
067        return getSingleNodePointerForSteps(rootContext);
068    }
069
070    /**
071     * Tests whether this LocationPath is absolute.
072     *
073     * @return boolean
074     */
075    public boolean isAbsolute() {
076        return absolute;
077    }
078
079    @Override
080    public String toString() {
081        final StringBuilder buffer = new StringBuilder();
082        final Step[] steps = getSteps();
083        if (steps != null) {
084            for (int i = 0; i < steps.length; i++) {
085                if (i > 0 || absolute) {
086                    buffer.append('/');
087                }
088                buffer.append(steps[i]);
089            }
090        }
091        return buffer.toString();
092    }
093}