001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether.internal.impl;
020
021import javax.inject.Named;
022import javax.inject.Singleton;
023
024import java.util.regex.Pattern;
025
026import org.eclipse.aether.ConfigurationProperties;
027import org.eclipse.aether.RepositorySystemSession;
028import org.eclipse.aether.impl.OfflineController;
029import org.eclipse.aether.repository.RemoteRepository;
030import org.eclipse.aether.transfer.RepositoryOfflineException;
031import org.eclipse.aether.util.ConfigUtils;
032
033import static java.util.Objects.requireNonNull;
034
035/**
036 *
037 */
038@Singleton
039@Named
040public class DefaultOfflineController implements OfflineController {
041    private static final String CONFIG_PROPS_PREFIX = ConfigurationProperties.PREFIX_AETHER + "offline.";
042
043    /**
044     * Comma-separated list of protocols which are supposed to be resolved offline.
045     *
046     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
047     * @configurationType {@link java.lang.String}
048     */
049    public static final String CONFIG_PROP_OFFLINE_PROTOCOLS = CONFIG_PROPS_PREFIX + "protocols";
050
051    /**
052     * Comma-separated list of hosts which are supposed to be resolved offline.
053     *
054     * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
055     * @configurationType {@link java.lang.String}
056     */
057    public static final String CONFIG_PROP_OFFLINE_HOSTS = CONFIG_PROPS_PREFIX + "hosts";
058
059    private static final Pattern SEP = Pattern.compile("\\s*,\\s*");
060
061    @Override
062    public void checkOffline(RepositorySystemSession session, RemoteRepository repository)
063            throws RepositoryOfflineException {
064        requireNonNull(session, "session cannot be null");
065        requireNonNull(repository, "repository cannot be null");
066        if (isOfflineProtocol(session, repository) || isOfflineHost(session, repository)) {
067            return;
068        }
069
070        throw new RepositoryOfflineException(repository);
071    }
072
073    private boolean isOfflineProtocol(RepositorySystemSession session, RemoteRepository repository) {
074        String[] protocols = getConfig(session, CONFIG_PROP_OFFLINE_PROTOCOLS);
075        if (protocols != null) {
076            String protocol = repository.getProtocol();
077            if (!protocol.isEmpty()) {
078                for (String p : protocols) {
079                    if (p.equalsIgnoreCase(protocol)) {
080                        return true;
081                    }
082                }
083            }
084        }
085        return false;
086    }
087
088    private boolean isOfflineHost(RepositorySystemSession session, RemoteRepository repository) {
089        String[] hosts = getConfig(session, CONFIG_PROP_OFFLINE_HOSTS);
090        if (hosts != null) {
091            String host = repository.getHost();
092            if (!host.isEmpty()) {
093                for (String h : hosts) {
094                    if (h.equalsIgnoreCase(host)) {
095                        return true;
096                    }
097                }
098            }
099        }
100        return false;
101    }
102
103    private String[] getConfig(RepositorySystemSession session, String key) {
104        String value = ConfigUtils.getString(session, "", key).trim();
105        if (value.isEmpty()) {
106            return null;
107        }
108        return SEP.split(value);
109    }
110}