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