1 /* 2 * Copyright (C) 2009 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; 18 19 import com.android.sdklib.internal.repository.Archive; 20 import com.android.sdklib.internal.repository.ArchiveReplacement; 21 22 import java.util.ArrayList; 23 import java.util.Collection; 24 25 /** 26 * Represents an archive that we want to install. 27 * Note that the installer deals with archives whereas the user mostly sees packages 28 * but as far as we are concerned for installation there's a 1-to-1 mapping. 29 * <p/> 30 * A new archive is always a remote archive that needs to be downloaded and then 31 * installed. It can replace an existing local one. It can also depends on another 32 * (new or local) archive, which means the dependent archive needs to be successfully 33 * installed first. Finally this archive can also be a dependency for another one. 34 * <p/> 35 * The accepted and rejected flags are used by {@link SdkUpdaterChooserDialog} to follow 36 * user choices. The installer should never install something that is not accepted. 37 * <p/> 38 * <em>Note</em>: There is currently no logic to support more than one level of 39 * dependency, either here or in the {@link SdkUpdaterChooserDialog}, since we currently 40 * have no need for it. 41 * 42 * @see ArchiveInfo#ArchiveInfo(Archive, Archive, ArchiveInfo[]) 43 */ 44 class ArchiveInfo extends ArchiveReplacement implements Comparable<ArchiveInfo> { 45 46 private final ArchiveInfo[] mDependsOn; 47 private final ArrayList<ArchiveInfo> mDependencyFor = new ArrayList<ArchiveInfo>(); 48 private boolean mAccepted; 49 private boolean mRejected; 50 51 /** 52 * Creates a new replacement where the {@code newArchive} will replace the 53 * currently installed {@code replaced} archive. 54 * When {@code newArchive} is not intended to replace anything (e.g. because 55 * the user is installing a new package not present on her system yet), then 56 * {@code replace} shall be null. 57 * 58 * @param newArchive A "new archive" to be installed. This is always an archive 59 * that comes from a remote site. This <em>may</em> be null. 60 * @param replaced An optional local archive that the new one will replace. 61 * Can be null if this archive does not replace anything. 62 * @param dependsOn An optional new or local dependency, that is an archive that 63 * <em>this</em> archive depends upon. In other words, we can only install 64 * this archive if the dependency has been successfully installed. It also 65 * means we need to install the dependency first. Can be null or empty. 66 * However it cannot contain nulls. 67 */ 68 public ArchiveInfo(Archive newArchive, Archive replaced, ArchiveInfo[] dependsOn) { 69 super(newArchive, replaced); 70 mDependsOn = dependsOn; 71 } 72 73 /** 74 * Returns an optional new or local dependency, that is an archive that <em>this</em> 75 * archive depends upon. In other words, we can only install this archive if the 76 * dependency has been successfully installed. It also means we need to install the 77 * dependency first. 78 * <p/> 79 * This array can be null or empty. It can't contain nulls though. 80 */ 81 public ArchiveInfo[] getDependsOn() { 82 return mDependsOn; 83 } 84 85 /** 86 * Returns true if this new archive is a dependency for <em>another</em> one that we 87 * want to install. 88 */ 89 public boolean isDependencyFor() { 90 return mDependencyFor.size() > 0; 91 } 92 93 /** 94 * Adds an {@link ArchiveInfo} for which <em>this</em> package is a dependency. 95 * This means the package added here depends on this package. 96 */ 97 public ArchiveInfo addDependencyFor(ArchiveInfo dependencyFor) { 98 if (!mDependencyFor.contains(dependencyFor)) { 99 mDependencyFor.add(dependencyFor); 100 } 101 102 return this; 103 } 104 105 /** 106 * Returns the list of {@link ArchiveInfo} for which <em>this</em> package is a dependency. 107 * This means the packages listed here depend on this package. 108 * <p/> 109 * Implementation detail: this is the internal mutable list. Callers should not modify it. 110 * This list can be empty but is never null. 111 */ 112 public Collection<ArchiveInfo> getDependenciesFor() { 113 return mDependencyFor; 114 } 115 116 /** 117 * Sets whether this archive was accepted (either manually by the user or 118 * automatically if it doesn't have a license) for installation. 119 */ 120 public void setAccepted(boolean accepted) { 121 mAccepted = accepted; 122 } 123 124 /** 125 * Returns whether this archive was accepted (either manually by the user or 126 * automatically if it doesn't have a license) for installation. 127 */ 128 public boolean isAccepted() { 129 return mAccepted; 130 } 131 132 /** 133 * Sets whether this archive was rejected manually by the user. 134 * An archive can neither accepted nor rejected. 135 */ 136 public void setRejected(boolean rejected) { 137 mRejected = rejected; 138 } 139 140 /** 141 * Returns whether this archive was rejected manually by the user. 142 * An archive can neither accepted nor rejected. 143 */ 144 public boolean isRejected() { 145 return mRejected; 146 } 147 148 /** 149 * ArchiveInfos are compared using ther "new archive" ordering. 150 * 151 * @see Archive#compareTo(Archive) 152 */ 153 public int compareTo(ArchiveInfo rhs) { 154 if (getNewArchive() != null && rhs != null) { 155 return getNewArchive().compareTo(rhs.getNewArchive()); 156 } 157 return 0; 158 } 159 } 160