• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
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 
17 package com.android.sdkuilib.internal.repository.sdkman2;
18 
19 import com.android.sdklib.internal.repository.Archive;
20 import com.android.sdklib.internal.repository.IPackageVersion;
21 import com.android.sdklib.internal.repository.Package;
22 import com.android.sdklib.internal.repository.Package.UpdateInfo;
23 import com.android.sdklib.internal.repository.SdkSource;
24 
25 /**
26  * A {@link PkgItem} represents one main {@link Package} combined with its state
27  * and an optional update package.
28  * <p/>
29  * The main package is final and cannot change since it's what "defines" this PkgItem.
30  * The state or update package can change later.
31  */
32 public class PkgItem implements Comparable<PkgItem> {
33     private final PkgState mState;
34     private final Package mMainPkg;
35     private Package mUpdatePkg;
36     private boolean mChecked;
37 
38     /**
39      * The state of the a given {@link PkgItem}, that is the relationship between
40      * a given remote package and the local repository.
41      */
42     public enum PkgState {
43         /**
44          * Package is locally installed and may or may not have an update.
45          */
46         INSTALLED,
47 
48         /**
49          * There's a new package available on the remote site that isn't installed locally.
50          */
51         NEW
52     }
53 
54     /**
55      * Create a new {@link PkgItem} for this main package.
56      * The main package is final and cannot change since it's what "defines" this PkgItem.
57      * The state or update package can change later.
58      */
PkgItem(Package mainPkg, PkgState state)59     public PkgItem(Package mainPkg, PkgState state) {
60         mMainPkg = mainPkg;
61         mState = state;
62         assert mMainPkg != null;
63     }
64 
isObsolete()65     public boolean isObsolete() {
66         return mMainPkg.isObsolete();
67     }
68 
isChecked()69     public boolean isChecked() {
70         return mChecked;
71     }
72 
setChecked(boolean checked)73     public void setChecked(boolean checked) {
74         mChecked = checked;
75     }
76 
getUpdatePkg()77     public Package getUpdatePkg() {
78         return mUpdatePkg;
79     }
80 
hasUpdatePkg()81     public boolean hasUpdatePkg() {
82         return mUpdatePkg != null;
83     }
84 
getName()85     public String getName() {
86         return mMainPkg.getListDescription();
87     }
88 
getRevision()89     public int getRevision() {
90         return mMainPkg.getRevision();
91     }
92 
getDescription()93     public String getDescription() {
94         return mMainPkg.getDescription();
95     }
96 
getMainPackage()97     public Package getMainPackage() {
98         return mMainPkg;
99     }
100 
getState()101     public PkgState getState() {
102         return mState;
103     }
104 
getSource()105     public SdkSource getSource() {
106         return mMainPkg.getParentSource();
107     }
108 
getApi()109     public int getApi() {
110         return mMainPkg instanceof IPackageVersion ?
111                 ((IPackageVersion) mMainPkg).getVersion().getApiLevel() :
112                     -1;
113     }
114 
getArchives()115     public Archive[] getArchives() {
116         return mMainPkg.getArchives();
117     }
118 
compareTo(PkgItem pkg)119     public int compareTo(PkgItem pkg) {
120         return getMainPackage().compareTo(pkg.getMainPackage());
121     }
122 
123     /**
124      * Returns true if this package or its updating packages contains
125      * the exact given archive.
126      * Important: This compares object references, not object equality.
127      */
hasArchive(Archive archive)128     public boolean hasArchive(Archive archive) {
129         if (mMainPkg.hasArchive(archive)) {
130             return true;
131         }
132         if (mUpdatePkg != null && mUpdatePkg.hasArchive(archive)) {
133             return true;
134         }
135         return false;
136     }
137 
138     /**
139      * Returns true if the main package has at least one archive
140      * compatible with the current platform.
141      */
hasCompatibleArchive()142     public boolean hasCompatibleArchive() {
143         return mMainPkg.hasCompatibleArchive();
144     }
145 
146     /**
147      * Checks whether the main packages are of the same type and are
148      * not an update of each other.
149      */
isSameMainPackageAs(Package pkg)150     public boolean isSameMainPackageAs(Package pkg) {
151         if (mMainPkg.canBeUpdatedBy(pkg) == UpdateInfo.NOT_UPDATE) {
152             // package revision numbers must match
153             return mMainPkg.getRevision() == pkg.getRevision();
154         }
155         return false;
156     }
157 
158     /**
159      * Checks whether too {@link PkgItem} are the same.
160      * This checks both items have the same state, both main package are similar
161      * and that they have the same updating packages.
162      */
isSameItemAs(PkgItem item)163     public boolean isSameItemAs(PkgItem item) {
164         if (this == item) {
165             return true;
166         }
167         boolean same = this.mState == item.mState;
168         if (same) {
169             same = isSameMainPackageAs(item.getMainPackage());
170         }
171 
172         if (same) {
173             // check updating packages are the same
174             Package p1 = this.mUpdatePkg;
175             Package p2 = item.getUpdatePkg();
176             same = (p1 == p2) || (p1 == null && p2 == null) || (p1 != null && p2 != null);
177 
178             if (same && p1 != null) {
179                 same = p1.canBeUpdatedBy(p2) == UpdateInfo.NOT_UPDATE;
180             }
181         }
182 
183         return same;
184     }
185 
186     /**
187      * Equality is defined as {@link #isSameItemAs(PkgItem)}: state, main package
188      * and update package must be the similar.
189      */
190     @Override
equals(Object obj)191     public boolean equals(Object obj) {
192         return (obj instanceof PkgItem) && this.isSameItemAs((PkgItem) obj);
193     }
194 
195     @Override
hashCode()196     public int hashCode() {
197         final int prime = 31;
198         int result = 1;
199         result = prime * result + ((mState     == null) ? 0 : mState.hashCode());
200         result = prime * result + ((mMainPkg   == null) ? 0 : mMainPkg.hashCode());
201         result = prime * result + ((mUpdatePkg == null) ? 0 : mUpdatePkg.hashCode());
202         return result;
203     }
204 
205     /**
206      * Check whether the 'pkg' argument is an update for this package.
207      * If it is, record it as an updating package.
208      * If there's already an updating package, only keep the most recent update.
209      * Returns true if it is update (even if there was already an update and this
210      * ended up not being the most recent), false if incompatible or not an update.
211      *
212      * This should only be used for installed packages.
213      */
mergeUpdate(Package pkg)214     public boolean mergeUpdate(Package pkg) {
215         if (mUpdatePkg == pkg) {
216             return true;
217         }
218         if (mMainPkg.canBeUpdatedBy(pkg) == UpdateInfo.UPDATE) {
219             if (mUpdatePkg == null) {
220                 mUpdatePkg = pkg;
221             } else if (mUpdatePkg.canBeUpdatedBy(pkg) == UpdateInfo.UPDATE) {
222                 // If we have more than one, keep only the most recent update
223                 mUpdatePkg = pkg;
224             }
225             return true;
226         }
227 
228         return false;
229     }
230 
removeUpdate()231     public void removeUpdate() {
232         mUpdatePkg = null;
233     }
234 
235     /** Returns a string representation of this item, useful when debugging. */
236     @Override
toString()237     public String toString() {
238         StringBuilder sb = new StringBuilder();
239         sb.append('<');
240 
241         if (mChecked) {
242             sb.append(" * "); //$NON-NLS-1$
243         }
244 
245         sb.append(mState.toString());
246 
247         if (mMainPkg != null) {
248             sb.append(", pkg:"); //$NON-NLS-1$
249             sb.append(mMainPkg.toString());
250         }
251 
252         if (mUpdatePkg != null) {
253             sb.append(", updated by:"); //$NON-NLS-1$
254             sb.append(mUpdatePkg.toString());
255         }
256 
257         sb.append('>');
258         return sb.toString();
259     }
260 
261 }
262