customize update strategy in Android Studio
[idea/community.git] / platform / platform-impl / src / com / intellij / openapi / updateSettings / impl / UpdateStrategy.java
1 /*
2  * Copyright 2000-2013 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.updateSettings.impl;
17
18 import com.intellij.openapi.updateSettings.UpdateStrategyCustomization;
19 import com.intellij.openapi.util.BuildNumber;
20 import org.jetbrains.annotations.NotNull;
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25 public class UpdateStrategy {
26   public enum State {LOADED, CONNECTION_ERROR, NOTHING_LOADED}
27
28   private UserUpdateSettings myUpdateSettings;
29   private int myMajorVersion;
30   private BuildNumber myCurrentBuild;
31
32   private ChannelStatus myChannelStatus;
33   private UpdatesInfo myUpdatesInfo;
34
35   public UpdateStrategy(int majorVersion,
36                         @NotNull BuildNumber currentBuild,
37                         @NotNull UpdatesInfo updatesInfo,
38                         @NotNull UserUpdateSettings updateSettings) {
39     myMajorVersion = majorVersion;
40     myUpdatesInfo = updatesInfo;
41     myUpdateSettings = updateSettings;
42     myCurrentBuild = currentBuild;
43     myChannelStatus = updateSettings.getSelectedChannelStatus();
44   }
45
46   public final CheckForUpdateResult checkForUpdates() {
47     final Product product = myUpdatesInfo.getProduct(myCurrentBuild.getProductCode());
48
49     if (product == null || product.getChannels().isEmpty()) {
50       return new CheckForUpdateResult(State.NOTHING_LOADED);
51     }
52
53     UpdateChannel updatedChannel = null;
54     BuildInfo newBuild = null;
55     List<UpdateChannel> activeChannels = getActiveChannels(product);
56     for (UpdateChannel channel : activeChannels) {
57       if (hasNewVersion(channel)) {
58         updatedChannel = channel;
59         newBuild = updatedChannel.getLatestBuild();
60         break;
61       }
62     }
63
64     CheckForUpdateResult result = new CheckForUpdateResult(updatedChannel, newBuild, product.getAllChannelIds());
65
66     UpdateChannel channelToPropose = null;
67     for (UpdateChannel channel : product.getChannels()) {
68       if (!myUpdateSettings.getKnownChannelsIds().contains(channel.getId()) &&
69           channel.getMajorVersion() >= myMajorVersion &&
70           channel.getStatus().compareTo(myChannelStatus) >= 0 &&
71           hasNewVersion(channel)) {
72         if (channelToPropose == null || isBetter(channelToPropose, channel)) {
73           channelToPropose = channel;
74         }
75       }
76     }
77     result.setChannelToPropose(channelToPropose);
78     return result;
79   }
80
81   private static boolean isBetter(UpdateChannel channelToPropose, UpdateChannel channel) {
82     return channel.getMajorVersion() > channelToPropose.getMajorVersion() ||
83            (channel.getMajorVersion() == channelToPropose.getMajorVersion() &&
84             channel.getStatus().compareTo(channelToPropose.getStatus()) > 0);
85   }
86
87   private List<UpdateChannel> getActiveChannels(Product product) {
88     List<UpdateChannel> channels = product.getChannels();
89     List<UpdateChannel> result = new ArrayList<UpdateChannel>();
90     for (UpdateChannel channel : channels) {
91
92       // If the update is to a new version and on a stabler channel, choose it.
93       if ((channel.getMajorVersion() >= myMajorVersion && channel.getStatus().compareTo(myChannelStatus) >= 0)) {
94         if (UpdateStrategyCustomization.getInstance().allowMajorVersionUpdate()
95             || channel.getMajorVersion() == myMajorVersion
96             || channel.getStatus() == ChannelStatus.EAP && myChannelStatus == ChannelStatus.EAP) {
97           // Prefer channel that has same status as our selected channel status
98           if (channel.getMajorVersion() == myMajorVersion && channel.getStatus().compareTo(myChannelStatus) == 0) {
99             result.add(0, channel);
100           }
101           else {
102             result.add(channel);
103           }
104         }
105       }
106     }
107     return result;
108   }
109
110   private boolean hasNewVersion(@NotNull UpdateChannel channel) {
111     BuildInfo latestBuild = channel.getLatestBuild();
112     if (latestBuild == null || latestBuild.getNumber() == null ||
113         myUpdateSettings.getIgnoredBuildNumbers().contains(latestBuild.getNumber().asStringWithoutProductCode())) {
114       return false;
115     }
116     return myCurrentBuild.compareTo(latestBuild.getNumber()) < 0;
117   }
118 }