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