<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.sling.resourceresolver.impl.providers.stateful;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.resourceresolver.impl.providers.tree.Node;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceProvider;

/**
 * Resolve context implementation for a resource provider.
 *
 * This class is not thread safe (same as the resource resolver).
 */
public class BasicResolveContext<T> implements ResolveContext<T> {

    private final ResourceResolver resolver;

    private final ProviderManager resolveContextManager;

    private final ResourceResolverControl control;

    private final T providerState;

    private final String parentPath;

    private volatile boolean parentLookupDone = false;

    private volatile ResourceProviderHandler parentProviderHandler;

    private volatile ResolveContext<Object> parentResolveContext;

    public BasicResolveContext(@Nonnull final ResourceResolver resolver,
            @Nonnull final ProviderManager resolveContextManager,
            @Nonnull final ResourceResolverControl control,
            @CheckForNull final T providerState,
            @Nonnull final String parentPath) {
        this.resolver = resolver;
        this.resolveContextManager = resolveContextManager;
        this.parentPath = parentPath;
        this.providerState = providerState;
        this.control = control;
    }

    @Override
    public ResourceResolver getResourceResolver() {
        return this.resolver;
    }

    @Override
    public T getProviderState() {
        return providerState;
    }

    @Override
    public ResolveContext<?> getParentResolveContext() {
        this.getParentResourceProvider();
        return parentResolveContext;
    }

    @Override
    public ResourceProvider<?> getParentResourceProvider() {
        if ( ! parentLookupDone ) {
            synchronized ( this ) {
                if ( this.parentPath != null ) {
                    String path = this.parentPath;
                    while ( path != null && this.parentProviderHandler != null ) {
                        final Node<ResourceProviderHandler> node = this.control.getResourceProviderStorage().getTree().getBestMatchingNode(this.parentPath);
                        if ( node != null ) {<commit_msg>SLING-5498 : ResolveContext#getParentResourceProvider always returns null<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.sling.resourceresolver.impl.providers.stateful;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
import org.apache.sling.resourceresolver.impl.providers.tree.Node;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceProvider;

/**
 * Resolve context implementation for a resource provider.
 *
 * This class is not thread safe (same as the resource resolver).
 */
public class BasicResolveContext<T> implements ResolveContext<T> {

    private final ResourceResolver resolver;

    private final ProviderManager resolveContextManager;

    private final ResourceResolverControl control;

    private final T providerState;

    private final String parentPath;

    private volatile boolean parentLookupDone = false;

    private volatile ResourceProviderHandler parentProviderHandler;

    private volatile ResolveContext<Object> parentResolveContext;

    public BasicResolveContext(@Nonnull final ResourceResolver resolver,
            @Nonnull final ProviderManager resolveContextManager,
            @Nonnull final ResourceResolverControl control,
            @CheckForNull final T providerState,
            @Nonnull final String parentPath) {
        this.resolver = resolver;
        this.resolveContextManager = resolveContextManager;
        this.parentPath = parentPath;
        this.providerState = providerState;
        this.control = control;
    }

    @Override
    public ResourceResolver getResourceResolver() {
        return this.resolver;
    }

    @Override
    public T getProviderState() {
        return providerState;
    }

    @Override
    public ResolveContext<?> getParentResolveContext() {
        this.getParentResourceProvider();
        return parentResolveContext;
    }

    @Override
    public ResourceProvider<?> getParentResourceProvider() {
        if ( ! parentLookupDone ) {
            synchronized ( this ) {
                if ( this.parentPath != null ) {
                    String path = this.parentPath;
                    while ( path != null && this.parentProviderHandler == null ) {
                        final Node<ResourceProviderHandler> node = this.control.getResourceProviderStorage().getTree().getBestMatchingNode(this.parentPath);
                        if ( node != null ) {
{'fraction_non_alphanumeric': 0.07207589917870291, 'fraction_numerical': 0.0016992353440951572, 'mean_word_length': 3.45615141955836, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1701193', 'n_tokens_mistral': 1731, 'n_tokens_neox': 1690, 'n_words': 538}