    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}