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    public DefaultUpdatePolicyAnalyzer() {
043        // enables default constructor
044    }
045
046    public String getEffectiveUpdatePolicy(RepositorySystemSession session, String policy1, String policy2) {
047        requireNonNull(session, "session cannot be null");
048        return ordinalOfUpdatePolicy(policy1) < ordinalOfUpdatePolicy(policy2) ? policy1 : policy2;
049    }
050
051    @SuppressWarnings({"checkstyle:magicnumber"})
052    private int ordinalOfUpdatePolicy(String policy) {
053        if (RepositoryPolicy.UPDATE_POLICY_DAILY.equals(policy)) {
054            return 1440;
055        } else if (RepositoryPolicy.UPDATE_POLICY_ALWAYS.equals(policy)) {
056            return 0;
057        } else if (policy != null && policy.startsWith(RepositoryPolicy.UPDATE_POLICY_INTERVAL)) {
058            return getMinutes(policy);
059        } else {
060            // assume "never"
061            return Integer.MAX_VALUE;
062        }
063    }
064
065    public boolean isUpdatedRequired(RepositorySystemSession session, long lastModified, String policy) {
066        requireNonNull(session, "session cannot be null");
067        boolean checkForUpdates;
068
069        if (policy == null) {
070            policy = "";
071        }
072
073        if (RepositoryPolicy.UPDATE_POLICY_ALWAYS.equals(policy)) {
074            checkForUpdates = true;
075        } else if (RepositoryPolicy.UPDATE_POLICY_DAILY.equals(policy)) {
076            Calendar cal = Calendar.getInstance();
077            cal.set(Calendar.HOUR_OF_DAY, 0);
078            cal.set(Calendar.MINUTE, 0);
079            cal.set(Calendar.SECOND, 0);
080            cal.set(Calendar.MILLISECOND, 0);
081
082            checkForUpdates = cal.getTimeInMillis() > lastModified;
083        } else if (policy.startsWith(RepositoryPolicy.UPDATE_POLICY_INTERVAL)) {
084            int minutes = getMinutes(policy);
085
086            Calendar cal = Calendar.getInstance();
087            cal.add(Calendar.MINUTE, -minutes);
088
089            checkForUpdates = cal.getTimeInMillis() > lastModified;
090        } else {
091            // assume "never"
092            checkForUpdates = false;
093
094            if (!RepositoryPolicy.UPDATE_POLICY_NEVER.equals(policy)) {
095                LOGGER.warn(
096                        "Unknown repository update policy '{}', assuming '{}'",
097                        policy,
098                        RepositoryPolicy.UPDATE_POLICY_NEVER);
099            }
100        }
101
102        return checkForUpdates;
103    }
104
105    @SuppressWarnings({"checkstyle:magicnumber"})
106    private int getMinutes(String policy) {
107        int minutes;
108        try {
109            String s = policy.substring(RepositoryPolicy.UPDATE_POLICY_INTERVAL.length() + 1);
110            minutes = Integer.parseInt(s);
111        } catch (RuntimeException e) {
112            minutes = 24 * 60;
113
114            LOGGER.warn(
115                    "Non-parseable repository update policy '{}', assuming '{}:1440'",
116                    policy,
117                    RepositoryPolicy.UPDATE_POLICY_INTERVAL);
118        }
119        return minutes;
120    }
121}