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