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.Calendar;
025
026import org.eclipse.aether.RepositorySystemSession;
027import org.eclipse.aether.impl.UpdatePolicyAnalyzer;
028import org.eclipse.aether.repository.RepositoryPolicy;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032import static java.util.Objects.requireNonNull;
033
034/**
035 */
036@Singleton
037@Named
038public class DefaultUpdatePolicyAnalyzer implements UpdatePolicyAnalyzer {
039
040    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultUpdatePolicyAnalyzer.class);
041
042    @Override
043    public String getEffectiveUpdatePolicy(RepositorySystemSession session, String policy1, String policy2) {
044        requireNonNull(session, "session cannot be null");
045        return ordinalOfUpdatePolicy(policy1) < ordinalOfUpdatePolicy(policy2) ? policy1 : policy2;
046    }
047
048    @Override
049    public String getStrongerUpdatePolicy(RepositorySystemSession session, String policy1, String policy2) {
050        requireNonNull(session, "session cannot be null");
051        return ordinalOfUpdatePolicy(policy1) > ordinalOfUpdatePolicy(policy2) ? policy1 : policy2;
052    }
053
054    private int ordinalOfUpdatePolicy(String policy) {
055        if (RepositoryPolicy.UPDATE_POLICY_DAILY.equals(policy)) {
056            return 1440;
057        } else if (RepositoryPolicy.UPDATE_POLICY_ALWAYS.equals(policy)) {
058            return 0;
059        } else if (policy != null && policy.startsWith(RepositoryPolicy.UPDATE_POLICY_INTERVAL)) {
060            return getMinutes(policy);
061        } else {
062            // assume "never"
063            return Integer.MAX_VALUE;
064        }
065    }
066
067    @Override
068    public boolean isUpdatedRequired(RepositorySystemSession session, long lastModified, String policy) {
069        requireNonNull(session, "session cannot be null");
070        boolean checkForUpdates;
071
072        if (policy == null) {
073            policy = "";
074        }
075
076        if (RepositoryPolicy.UPDATE_POLICY_ALWAYS.equals(policy)) {
077            checkForUpdates = true;
078        } else if (RepositoryPolicy.UPDATE_POLICY_DAILY.equals(policy)) {
079            Calendar cal = Calendar.getInstance();
080            cal.set(Calendar.HOUR_OF_DAY, 0);
081            cal.set(Calendar.MINUTE, 0);
082            cal.set(Calendar.SECOND, 0);
083            cal.set(Calendar.MILLISECOND, 0);
084
085            checkForUpdates = cal.getTimeInMillis() > lastModified;
086        } else if (policy.startsWith(RepositoryPolicy.UPDATE_POLICY_INTERVAL)) {
087            int minutes = getMinutes(policy);
088
089            Calendar cal = Calendar.getInstance();
090            cal.add(Calendar.MINUTE, -minutes);
091
092            checkForUpdates = cal.getTimeInMillis() > lastModified;
093        } else {
094            // assume "never"
095            checkForUpdates = false;
096
097            if (!RepositoryPolicy.UPDATE_POLICY_NEVER.equals(policy)) {
098                LOGGER.warn(
099                        "Unknown repository update policy '{}', assuming '{}'",
100                        policy,
101                        RepositoryPolicy.UPDATE_POLICY_NEVER);
102            }
103        }
104
105        return checkForUpdates;
106    }
107
108    private int getMinutes(String policy) {
109        int minutes;
110        try {
111            String s = policy.substring(RepositoryPolicy.UPDATE_POLICY_INTERVAL.length() + 1);
112            minutes = Integer.parseInt(s);
113        } catch (RuntimeException e) {
114            minutes = 24 * 60;
115
116            LOGGER.warn(
117                    "Non-parseable repository update policy '{}', assuming '{}:1440'",
118                    policy,
119                    RepositoryPolicy.UPDATE_POLICY_INTERVAL);
120        }
121        return minutes;
122    }
123}