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.lang3;
018
019import java.util.Objects;
020
021/**
022 * Operations regarding the classpath.
023 *
024 * <p>
025 * The methods of this class do not allow {@code null} inputs.
026 * </p>
027 *
028 * @since 3.3
029 */
030//@Immutable
031public class ClassPathUtils {
032
033    /**
034     * Converts a package name to a Java path ('/').
035     *
036     * @param path the source path.
037     * @return a package name.
038     * @throws NullPointerException if {@code path} is null.
039     * @since 3.13.0
040     */
041    public static String packageToPath(final String path) {
042        return Objects.requireNonNull(path, "path").replace('.', '/');
043    }
044
045    /**
046     * Converts a Java path ('/') to a package name.
047     *
048     * @param path the source path.
049     * @return a package name.
050     * @throws NullPointerException if {@code path} is null.
051     * @since 3.13.0
052     */
053    public static String pathToPackage(final String path) {
054        return Objects.requireNonNull(path, "path").replace('/', '.');
055    }
056
057    /**
058     * Returns the fully qualified name for the resource with name {@code resourceName} relative to the given context.
059     *
060     * <p>
061     * Note that this method does not check whether the resource actually exists. It only constructs the name. Null inputs are not allowed.
062     * </p>
063     *
064     * <pre>
065     * ClassPathUtils.toFullyQualifiedName(StringUtils.class, "StringUtils.properties") = "org.apache.commons.lang3.StringUtils.properties"
066     * </pre>
067     *
068     * @param context      The context for constructing the name.
069     * @param resourceName the resource name to construct the fully qualified name for.
070     * @return the fully qualified name of the resource with name {@code resourceName}.
071     * @throws NullPointerException if either {@code context} or {@code resourceName} is null.
072     */
073    public static String toFullyQualifiedName(final Class<?> context, final String resourceName) {
074        Objects.requireNonNull(context, "context");
075        Objects.requireNonNull(resourceName, "resourceName");
076        return toFullyQualifiedName(context.getPackage(), resourceName);
077    }
078
079    /**
080     * Returns the fully qualified name for the resource with name {@code resourceName} relative to the given context.
081     *
082     * <p>
083     * Note that this method does not check whether the resource actually exists. It only constructs the name. Null inputs are not allowed.
084     * </p>
085     *
086     * <pre>
087     * ClassPathUtils.toFullyQualifiedName(StringUtils.class.getPackage(), "StringUtils.properties") = "org.apache.commons.lang3.StringUtils.properties"
088     * </pre>
089     *
090     * @param context      The context for constructing the name.
091     * @param resourceName the resource name to construct the fully qualified name for.
092     * @return the fully qualified name of the resource with name {@code resourceName}.
093     * @throws NullPointerException if either {@code context} or {@code resourceName} is null.
094     */
095    public static String toFullyQualifiedName(final Package context, final String resourceName) {
096        Objects.requireNonNull(context, "context");
097        Objects.requireNonNull(resourceName, "resourceName");
098        return context.getName() + "." + resourceName;
099    }
100
101    /**
102     * Returns the fully qualified path for the resource with name {@code resourceName} relative to the given context.
103     *
104     * <p>
105     * Note that this method does not check whether the resource actually exists. It only constructs the path. Null inputs are not allowed.
106     * </p>
107     *
108     * <pre>
109     * ClassPathUtils.toFullyQualifiedPath(StringUtils.class, "StringUtils.properties") = "org/apache/commons/lang3/StringUtils.properties"
110     * </pre>
111     *
112     * @param context      The context for constructing the path.
113     * @param resourceName the resource name to construct the fully qualified path for.
114     * @return the fully qualified path of the resource with name {@code resourceName}.
115     * @throws NullPointerException if either {@code context} or {@code resourceName} is null.
116     */
117    public static String toFullyQualifiedPath(final Class<?> context, final String resourceName) {
118        Objects.requireNonNull(context, "context");
119        Objects.requireNonNull(resourceName, "resourceName");
120        return toFullyQualifiedPath(context.getPackage(), resourceName);
121    }
122
123    /**
124     * Returns the fully qualified path for the resource with name {@code resourceName} relative to the given context.
125     *
126     * <p>
127     * Note that this method does not check whether the resource actually exists. It only constructs the path. Null inputs are not allowed.
128     * </p>
129     *
130     * <pre>
131     * ClassPathUtils.toFullyQualifiedPath(StringUtils.class.getPackage(), "StringUtils.properties") = "org/apache/commons/lang3/StringUtils.properties"
132     * </pre>
133     *
134     * @param context      The context for constructing the path.
135     * @param resourceName the resource name to construct the fully qualified path for.
136     * @return the fully qualified path of the resource with name {@code resourceName}.
137     * @throws NullPointerException if either {@code context} or {@code resourceName} is null.
138     */
139    public static String toFullyQualifiedPath(final Package context, final String resourceName) {
140        Objects.requireNonNull(context, "context");
141        Objects.requireNonNull(resourceName, "resourceName");
142        return packageToPath(context.getName()) + "/" + resourceName;
143    }
144
145    /**
146     * {@link ClassPathUtils} instances should NOT be constructed in standard programming. Instead, the class should be used as
147     * {@code ClassPathUtils.toFullyQualifiedName(MyClass.class, "MyClass.properties");}.
148     *
149     * <p>
150     * This constructor is public to permit tools that require a JavaBean instance to operate.
151     * </p>
152     */
153    public ClassPathUtils() {
154    }
155
156}