<commit_before>/*
 * Copyright 2005 The Apache Software Foundation.
 *
 * Licensed 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.jackrabbit.webdav.jcr;

import org.apache.log4j.Logger;
import org.apache.jackrabbit.webdav.DavResourceLocator;
import org.apache.jackrabbit.webdav.DavLocatorFactory;
import org.apache.jackrabbit.util.Text;

/**
 * <code>DavLocatorFactoryImpl</code>...
 */
public class DavLocatorFactoryImpl implements DavLocatorFactory {

    private static Logger log = Logger.getLogger(DavLocatorFactoryImpl.class);

    private final String pathPrefix;

    /**
     * Create a new factory
     *
     * @param pathPrefix Prefix, that needs to be removed in order to retrieve
     *                   the path of the repository item from a given <code>DavResourceLocator</code>.
     */
    public DavLocatorFactoryImpl(String pathPrefix) {
        this.pathPrefix = pathPrefix;
    }

    /**
     * Create a new <code>DavResourceLocator</code>. Any leading
     * path-prefix (as defined with the constructor) and trailing '/' with
     * the request handle is removed. The first label of the remaining handle is
     * treated as workspace name. The remaining part of the given request handle
     * is said to be the resource handle ("/" if an empty string remains).
     * If the request handle does neither provide workspace name nor resource
     * handle both values are set to <code>null</code>; the path object then
     * represents the root resource that has no corresponding item in the JCR
     * repository.
     *
     * @param prefix
     * @param href
     * @return a new <code>DavResourceLocator</code>
     * @throws IllegalArgumentException if the request handle is <code>null</code>
     */
    public DavResourceLocator createResourceLocator(String prefix, String href) {
        if (href == null) {
            throw new IllegalArgumentException("Request handle must not be null.");
        }

        StringBuffer b = new StringBuffer("");
        if (prefix != null) {
            b.append(prefix);
            if (pathPrefix != null && !prefix.endsWith(pathPrefix)) {
                b.append(pathPrefix);
            }
        }
        String rlPrefix = b.toString();

        // remove any prefix that may still be present with the given href
        if (pathPrefix != null && href.startsWith(pathPrefix)) {
            href = href.substring(pathPrefix.length());
        } else if (!"".equals(rlPrefix) && href.startsWith(rlPrefix)) {
            href = href.substring(rlPrefix.length());
        }

        // remove trailing "/" that is present with collections
        if (href.endsWith("/")) {
            href = href.substring(0, href.length() - 1);
        }

        String resourcePath;
        String workspacePath;

        // an empty requestHandle (after removal of the "/") signifies a request
        // to the root that does not represent a repository item.
        if ("".equals(href)) {
            resourcePath = null;
            workspacePath = null;
        } else {
            // look for the first slash ignoring the leading one
            int pos = href.indexOf('/', 1);
            if (pos == -1) {
                // request to a 'workspace' resource that in the same time
                // represent the root node of the repository.
                workspacePath = href;
                resourcePath = ItemResourceConstants.ROOT_ITEM_PATH;
            } else {
                // separate the workspace name from the path of the repository
                // item.
                workspacePath = href.substring(0, pos);
                resourcePath = Text.unescape(href.substring(pos));
            }
        }

        return new DavResourceLocatorImpl(rlPrefix, workspacePath, resourcePath, this);
    }

    /**
     * Create a new <code>DavResourceLocator</code> from the specified prefix,
     * workspace path and resource path, whithout modifying the specified Strings.
     *
     * @param prefix
     * @param workspacePath
     * @param resourcePath
     * @return a new <code>DavResourceLocator</code>
     * @see DavLocatorFactory#createResourceLocator(String, String, String)
     */
    public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String resourcePath) {
        return createResourceLocator(prefix, workspacePath, resourcePath, true);
    }

    /**
     *
     * @param prefix
     * @param workspacePath
     * @param path
     * @param isResourcePath
     * @return
     * @see DavLocatorFactory#createResourceLocator(String, String, String, boolean)
     */
    public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String path, boolean isResourcePath) {
        return new DavResourceLocatorImpl(prefix, workspacePath, path, this);
    }

    /**
     * Private inner class <code>DavResourceLocatorImpl</code> implementing
     * the <code>DavResourceLocator</code> interface.
     */
    private class DavResourceLocatorImpl implements DavResourceLocator {

        private final String prefix;
        private final String workspacePath;
        private final String resourcePath;
        private final DavLocatorFactory factory;

        private final String href;

        /**
         * Create a new <code>DavResourceLocatorImpl</code>.
         *
         * @param prefix
         * @param workspacePath
         * @param resourcePath
         */
        DavResourceLocatorImpl(String prefix, String workspacePath, String resourcePath, DavLocatorFactory factory) {
            this.prefix = prefix;
            this.workspacePath = workspacePath;
            this.resourcePath = resourcePath;
            this.factory = factory;

            StringBuffer buf = new StringBuffer(prefix);
            if (workspacePath != null) {
                buf.append(workspacePath);
            }
            if (resourcePath != null) {
                buf.append(Text.escapePath(resourcePath));
            }
            if (buf.charAt(buf.length() - 1) != '/') {
                buf.append("/");
            }
            href = buf.toString();
        }

        /**
         * Return the prefix used to build the href String. This includes the initial
         * hrefPrefix as well a the path prefix.
         *<commit_msg>avoid StringIndexOutOfBoundsException in case of invalid resource path.<commit_after>/*
 * Copyright 2005 The Apache Software Foundation.
 *
 * Licensed 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.jackrabbit.webdav.jcr;

import org.apache.log4j.Logger;
import org.apache.jackrabbit.webdav.DavResourceLocator;
import org.apache.jackrabbit.webdav.DavLocatorFactory;
import org.apache.jackrabbit.util.Text;

/**
 * <code>DavLocatorFactoryImpl</code>...
 */
public class DavLocatorFactoryImpl implements DavLocatorFactory {

    private static Logger log = Logger.getLogger(DavLocatorFactoryImpl.class);

    private final String pathPrefix;

    /**
     * Create a new factory
     *
     * @param pathPrefix Prefix, that needs to be removed in order to retrieve
     *                   the path of the repository item from a given <code>DavResourceLocator</code>.
     */
    public DavLocatorFactoryImpl(String pathPrefix) {
        this.pathPrefix = pathPrefix;
    }

    /**
     * Create a new <code>DavResourceLocator</code>. Any leading
     * path-prefix (as defined with the constructor) and trailing '/' with
     * the request handle is removed. The first label of the remaining handle is
     * treated as workspace name. The remaining part of the given request handle
     * is said to be the resource handle ("/" if an empty string remains).
     * If the request handle does neither provide workspace name nor resource
     * handle both values are set to <code>null</code>; the path object then
     * represents the root resource that has no corresponding item in the JCR
     * repository.
     *
     * @param prefix
     * @param href
     * @return a new <code>DavResourceLocator</code>
     * @throws IllegalArgumentException if the request handle is <code>null</code>
     */
    public DavResourceLocator createResourceLocator(String prefix, String href) {
        if (href == null) {
            throw new IllegalArgumentException("Request handle must not be null.");
        }

        StringBuffer b = new StringBuffer("");
        if (prefix != null) {
            b.append(prefix);
            if (pathPrefix != null && !prefix.endsWith(pathPrefix)) {
                b.append(pathPrefix);
            }
        }
        String rlPrefix = b.toString();

        // remove any prefix that may still be present with the given href
        if (pathPrefix != null && href.startsWith(pathPrefix)) {
            href = href.substring(pathPrefix.length());
        } else if (!"".equals(rlPrefix) && href.startsWith(rlPrefix)) {
            href = href.substring(rlPrefix.length());
        }

        // remove trailing "/" that is present with collections
        if (href.endsWith("/")) {
            href = href.substring(0, href.length() - 1);
        }

        String resourcePath;
        String workspacePath;

        // an empty requestHandle (after removal of the "/") signifies a request
        // to the root that does not represent a repository item.
        if ("".equals(href)) {
            resourcePath = null;
            workspacePath = null;
        } else {
            // look for the first slash ignoring the leading one
            int pos = href.indexOf('/', 1);
            if (pos == -1) {
                // request to a 'workspace' resource that in the same time
                // represent the root node of the repository.
                workspacePath = href;
                resourcePath = ItemResourceConstants.ROOT_ITEM_PATH;
            } else {
                // separate the workspace name from the path of the repository
                // item.
                workspacePath = href.substring(0, pos);
                resourcePath = Text.unescape(href.substring(pos));
            }
        }

        return new DavResourceLocatorImpl(rlPrefix, workspacePath, resourcePath, this);
    }

    /**
     * Create a new <code>DavResourceLocator</code> from the specified prefix,
     * workspace path and resource path, whithout modifying the specified Strings.
     *
     * @param prefix
     * @param workspacePath
     * @param resourcePath
     * @return a new <code>DavResourceLocator</code>
     * @see DavLocatorFactory#createResourceLocator(String, String, String)
     */
    public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String resourcePath) {
        return createResourceLocator(prefix, workspacePath, resourcePath, true);
    }

    /**
     *
     * @param prefix
     * @param workspacePath
     * @param path
     * @param isResourcePath
     * @return
     * @see DavLocatorFactory#createResourceLocator(String, String, String, boolean)
     */
    public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String path, boolean isResourcePath) {
        return new DavResourceLocatorImpl(prefix, workspacePath, path, this);
    }

    /**
     * Private inner class <code>DavResourceLocatorImpl</code> implementing
     * the <code>DavResourceLocator</code> interface.
     */
    private class DavResourceLocatorImpl implements DavResourceLocator {

        private final String prefix;
        private final String workspacePath;
        private final String resourcePath;
        private final DavLocatorFactory factory;

        private final String href;

        /**
         * Create a new <code>DavResourceLocatorImpl</code>.
         *
         * @param prefix
         * @param workspacePath
         * @param resourcePath
         */
        DavResourceLocatorImpl(String prefix, String workspacePath, String resourcePath, DavLocatorFactory factory) {
            this.prefix = prefix;
            this.workspacePath = workspacePath;
            this.resourcePath = resourcePath;
            this.factory = factory;

            StringBuffer buf = new StringBuffer(prefix);
            if (workspacePath != null) {
                buf.append(workspacePath);
            }
            if (resourcePath != null) {
                buf.append(Text.escapePath(resourcePath));
            }
            int length = buf.length();
            if (length > 0 && buf.charAt(length - 1) != '/') {
                buf.append("/");
            }
            href = buf.toString();
        }

        /**
         * Return the prefix used to build the href String. This includes the initial
         * hrefPrefix as well a the path prefix.
         *
{'fraction_non_alphanumeric': 0.08666521010851358, 'fraction_numerical': 0.002257665137280606, 'mean_word_length': 2.328969696969697, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 48, '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': '4235264', 'n_tokens_mistral': 3471, 'n_tokens_neox': 3360, 'n_words': 1166}