001/**
002 * Copyright (C) 2006-2024 Talend Inc. - www.talend.com
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.talend.sdk.component.runtime.manager.service.path;
017
018import java.nio.file.Files;
019import java.nio.file.InvalidPathException;
020import java.nio.file.Path;
021import java.nio.file.Paths;
022import java.util.regex.Matcher;
023import java.util.regex.Pattern;
024
025import lombok.extern.slf4j.Slf4j;
026
027@Slf4j
028public class PathHandlerImpl implements PathHandler {
029
030    // maven property regexp
031    private static final Pattern MVN_PROPERTY = Pattern.compile("^\\$\\{(.*)\\}(.*)");
032
033    // interpolate predicate regexp
034    private static final Pattern INTERPOLATE_P = Pattern.compile("^(\\$\\{(.*)\\}|~|/.:).*");
035
036    /**
037     * Potentially interpolate or modify part of the path to have a full parsable path for the framework.
038     *
039     * @param path the value to inspect and eventually modify.
040     *
041     * @return a {@link Path} with interpolated elements.
042     */
043    protected Path interpolate(final String path) {
044        String p = path;
045        // skip this directly if not needed...
046        if (INTERPOLATE_P.matcher(path).matches()) {
047            // windows
048            if (p.startsWith("/") && p.indexOf(':') == 2) {
049                p = p.substring(1);
050            }
051            // unix ~ : we shouldn't have the case as it's shell parsed only normally
052            if (p.startsWith("~")) {
053                p = System.getProperty("user.home") + p.substring(1);
054            }
055            // parse any maven property : more likely to be used
056            final Matcher matcher = MVN_PROPERTY.matcher(p);
057            if (matcher.matches()) {
058                final String prop = matcher.group(1);
059                String value;
060                if (prop.startsWith("env.")) {
061                    value = System.getenv(prop.substring("env.".length()));
062                } else {
063                    value = System.getProperty(prop);
064                }
065                p = value + matcher.group(2);
066            }
067        }
068
069        try {
070            return Paths.get(p);
071        } catch (InvalidPathException e) {
072            log.debug("[PathHandlerImpl] not valid path: {}.", p);
073            return null;
074        }
075    }
076
077    /**
078     * Check path existence
079     *
080     * @param path value to check
081     *
082     * @return null if path do not exist, path otherwise
083     */
084    protected Path exist(final Path path) {
085        if (path != null && Files.exists(path)) {
086            return path;
087        }
088        log.debug("[PathHandlerImpl] non existent path: {}.", path);
089
090        return null;
091    }
092
093    @Override
094    public Path get(final String path) {
095        return exist(interpolate(path));
096    }
097}