Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 Google Inc. |
| 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.google.doclava; |
| 18 | |
Mathieu | 11b1796 | 2013-06-07 17:24:18 -0500 | [diff] [blame] | 19 | import com.google.doclava.apicheck.ApiInfo; |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 20 | import com.google.clearsilver.jsilver.data.Data; |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 21 | import com.sun.javadoc.*; |
Guang Zhu | f9b7c1b | 2015-04-24 16:45:42 -0700 | [diff] [blame^] | 22 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 23 | import java.util.*; |
| 24 | |
| 25 | public class PackageInfo extends DocInfo implements ContainerInfo { |
| 26 | public static final String DEFAULT_PACKAGE = "default package"; |
Scott Main | 3c1a6b2 | 2010-10-15 17:34:04 -0700 | [diff] [blame] | 27 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 28 | public static final Comparator<PackageInfo> comparator = new Comparator<PackageInfo>() { |
| 29 | public int compare(PackageInfo a, PackageInfo b) { |
| 30 | return a.name().compareTo(b.name()); |
| 31 | } |
| 32 | }; |
| 33 | |
| 34 | public PackageInfo(PackageDoc pkg, String name, SourcePositionInfo position) { |
| 35 | super(pkg.getRawCommentText(), position); |
| 36 | if (name.isEmpty()) { |
| 37 | mName = DEFAULT_PACKAGE; |
| 38 | } else { |
| 39 | mName = name; |
| 40 | } |
| 41 | |
| 42 | mPackage = pkg; |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 43 | initializeMaps(); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 44 | } |
Scott Main | 3c1a6b2 | 2010-10-15 17:34:04 -0700 | [diff] [blame] | 45 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 46 | public PackageInfo(String name) { |
| 47 | super("", null); |
| 48 | mName = name; |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 49 | initializeMaps(); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 50 | } |
Scott Main | 3c1a6b2 | 2010-10-15 17:34:04 -0700 | [diff] [blame] | 51 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 52 | public PackageInfo(String name, SourcePositionInfo position) { |
| 53 | super("", position); |
Scott Main | 3c1a6b2 | 2010-10-15 17:34:04 -0700 | [diff] [blame] | 54 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 55 | if (name.isEmpty()) { |
| 56 | mName = "default package"; |
| 57 | } else { |
| 58 | mName = name; |
| 59 | } |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 60 | initializeMaps(); |
| 61 | } |
| 62 | |
| 63 | private void initializeMaps() { |
Brett Chabot | 700b9f2 | 2013-10-04 16:57:39 -0700 | [diff] [blame] | 64 | mAnnotationsMap = new HashMap<String, ClassInfo>(); |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 65 | mInterfacesMap = new HashMap<String, ClassInfo>(); |
| 66 | mOrdinaryClassesMap = new HashMap<String, ClassInfo>(); |
| 67 | mEnumsMap = new HashMap<String, ClassInfo>(); |
| 68 | mExceptionsMap = new HashMap<String, ClassInfo>(); |
| 69 | mErrorsMap = new HashMap<String, ClassInfo>(); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 70 | } |
| 71 | |
| 72 | public String htmlPage() { |
| 73 | String s = mName; |
| 74 | s = s.replace('.', '/'); |
| 75 | s += "/package-summary.html"; |
| 76 | s = Doclava.javadocDir + s; |
| 77 | return s; |
| 78 | } |
| 79 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 80 | @Override |
| 81 | public ContainerInfo parent() { |
| 82 | return null; |
| 83 | } |
| 84 | |
| 85 | @Override |
| 86 | public boolean isHidden() { |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 87 | if (mHidden == null) { |
Adam Metcalf | f2d2e93 | 2013-08-19 17:12:24 -0700 | [diff] [blame] | 88 | if (hasHideComment()) { |
| 89 | // We change the hidden value of the package if a class wants to be not hidden. |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 90 | ClassInfo[][] types = new ClassInfo[][] { annotations(), interfaces(), ordinaryClasses(), |
| 91 | enums(), exceptions() }; |
Adam Metcalf | f2d2e93 | 2013-08-19 17:12:24 -0700 | [diff] [blame] | 92 | for (ClassInfo[] type : types) { |
| 93 | if (type != null) { |
| 94 | for (ClassInfo c : type) { |
| 95 | if (c.hasShowAnnotation()) { |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 96 | mHidden = false; |
Adam Metcalf | f2d2e93 | 2013-08-19 17:12:24 -0700 | [diff] [blame] | 97 | return false; |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | } |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 102 | mHidden = true; |
Adam Metcalf | f2d2e93 | 2013-08-19 17:12:24 -0700 | [diff] [blame] | 103 | } else { |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 104 | mHidden = false; |
Adam Metcalf | f2d2e93 | 2013-08-19 17:12:24 -0700 | [diff] [blame] | 105 | } |
| 106 | } |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 107 | return mHidden; |
| 108 | } |
| 109 | |
| 110 | @Override |
| 111 | public boolean isRemoved() { |
| 112 | if (mRemoved == null) { |
| 113 | if (hasRemovedComment()) { |
| 114 | // We change the removed value of the package if a class wants to be not hidden. |
| 115 | ClassInfo[][] types = new ClassInfo[][] { annotations(), interfaces(), ordinaryClasses(), |
| 116 | enums(), exceptions() }; |
| 117 | for (ClassInfo[] type : types) { |
| 118 | if (type != null) { |
| 119 | for (ClassInfo c : type) { |
| 120 | if (c.hasShowAnnotation()) { |
| 121 | mRemoved = false; |
| 122 | return false; |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | } |
| 127 | mRemoved = true; |
| 128 | } else { |
| 129 | mRemoved = false; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | return mRemoved; |
| 134 | } |
| 135 | |
| 136 | @Override |
| 137 | public boolean isHiddenOrRemoved() { |
| 138 | return isHidden() || isRemoved(); |
Adam Metcalf | f2d2e93 | 2013-08-19 17:12:24 -0700 | [diff] [blame] | 139 | } |
| 140 | |
| 141 | /** |
| 142 | * Used by ClassInfo to determine packages default visability before annoations. |
| 143 | */ |
| 144 | public boolean hasHideComment() { |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 145 | if (mHiddenByComment == null) { |
Alex Klyubin | cbc60de | 2014-06-03 16:53:17 -0700 | [diff] [blame] | 146 | if (Doclava.hiddenPackages.contains(mName)) { |
| 147 | mHiddenByComment = true; |
| 148 | } else { |
| 149 | mHiddenByComment = comment().isHidden(); |
| 150 | } |
Adam Metcalf | f2d2e93 | 2013-08-19 17:12:24 -0700 | [diff] [blame] | 151 | } |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 152 | return mHiddenByComment; |
| 153 | } |
| 154 | |
| 155 | public boolean hasRemovedComment() { |
| 156 | if (mRemovedByComment == null) { |
| 157 | mRemovedByComment = comment().isRemoved(); |
| 158 | } |
| 159 | |
| 160 | return mRemovedByComment; |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | public boolean checkLevel() { |
| 164 | // TODO should return false if all classes are hidden but the package isn't. |
| 165 | // We don't have this so I'm not doing it now. |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 166 | return !isHiddenOrRemoved(); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 167 | } |
| 168 | |
| 169 | public String name() { |
| 170 | return mName; |
| 171 | } |
| 172 | |
| 173 | public String qualifiedName() { |
| 174 | return mName; |
| 175 | } |
| 176 | |
| 177 | public TagInfo[] inlineTags() { |
| 178 | return comment().tags(); |
| 179 | } |
| 180 | |
| 181 | public TagInfo[] firstSentenceTags() { |
| 182 | return comment().briefTags(); |
| 183 | } |
| 184 | |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 185 | /** |
| 186 | * @param classes the Array of ClassInfo to be filtered |
| 187 | * @return an Array of ClassInfo without any hidden or removed classes |
| 188 | */ |
| 189 | public static ClassInfo[] filterHiddenAndRemoved(ClassInfo[] classes) { |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 190 | ArrayList<ClassInfo> out = new ArrayList<ClassInfo>(); |
| 191 | |
| 192 | for (ClassInfo cl : classes) { |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 193 | if (!cl.isHiddenOrRemoved()) { |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 194 | out.add(cl); |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | return out.toArray(new ClassInfo[0]); |
| 199 | } |
| 200 | |
| 201 | public void makeLink(Data data, String base) { |
| 202 | if (checkLevel()) { |
| 203 | data.setValue(base + ".link", htmlPage()); |
| 204 | } |
| 205 | data.setValue(base + ".name", name()); |
| 206 | data.setValue(base + ".since", getSince()); |
| 207 | } |
| 208 | |
| 209 | public void makeClassLinkListHDF(Data data, String base) { |
| 210 | makeLink(data, base); |
Brett Chabot | 700b9f2 | 2013-10-04 16:57:39 -0700 | [diff] [blame] | 211 | ClassInfo.makeLinkListHDF(data, base + ".annotations", annotations()); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 212 | ClassInfo.makeLinkListHDF(data, base + ".interfaces", interfaces()); |
| 213 | ClassInfo.makeLinkListHDF(data, base + ".classes", ordinaryClasses()); |
| 214 | ClassInfo.makeLinkListHDF(data, base + ".enums", enums()); |
| 215 | ClassInfo.makeLinkListHDF(data, base + ".exceptions", exceptions()); |
| 216 | ClassInfo.makeLinkListHDF(data, base + ".errors", errors()); |
| 217 | data.setValue(base + ".since", getSince()); |
| 218 | } |
| 219 | |
Brett Chabot | 700b9f2 | 2013-10-04 16:57:39 -0700 | [diff] [blame] | 220 | public ClassInfo[] annotations() { |
| 221 | if (mAnnotations == null) { |
| 222 | mAnnotations = |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 223 | ClassInfo.sortByName(filterHiddenAndRemoved( |
| 224 | Converter.convertClasses(mPackage.annotationTypes()))); |
Brett Chabot | 700b9f2 | 2013-10-04 16:57:39 -0700 | [diff] [blame] | 225 | } |
| 226 | return mAnnotations; |
| 227 | } |
| 228 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 229 | public ClassInfo[] interfaces() { |
| 230 | if (mInterfaces == null) { |
| 231 | mInterfaces = |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 232 | ClassInfo.sortByName(filterHiddenAndRemoved( |
| 233 | Converter.convertClasses(mPackage.interfaces()))); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 234 | } |
| 235 | return mInterfaces; |
| 236 | } |
| 237 | |
| 238 | public ClassInfo[] ordinaryClasses() { |
| 239 | if (mOrdinaryClasses == null) { |
| 240 | mOrdinaryClasses = |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 241 | ClassInfo.sortByName(filterHiddenAndRemoved( |
| 242 | Converter.convertClasses(mPackage.ordinaryClasses()))); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 243 | } |
| 244 | return mOrdinaryClasses; |
| 245 | } |
| 246 | |
| 247 | public ClassInfo[] enums() { |
| 248 | if (mEnums == null) { |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 249 | mEnums = ClassInfo.sortByName(filterHiddenAndRemoved( |
| 250 | Converter.convertClasses(mPackage.enums()))); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 251 | } |
| 252 | return mEnums; |
| 253 | } |
| 254 | |
| 255 | public ClassInfo[] exceptions() { |
| 256 | if (mExceptions == null) { |
| 257 | mExceptions = |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 258 | ClassInfo.sortByName(filterHiddenAndRemoved( |
| 259 | Converter.convertClasses(mPackage.exceptions()))); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 260 | } |
| 261 | return mExceptions; |
| 262 | } |
| 263 | |
| 264 | public ClassInfo[] errors() { |
| 265 | if (mErrors == null) { |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 266 | mErrors = ClassInfo.sortByName(filterHiddenAndRemoved( |
| 267 | Converter.convertClasses(mPackage.errors()))); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 268 | } |
| 269 | return mErrors; |
| 270 | } |
| 271 | |
Mathieu | 11b1796 | 2013-06-07 17:24:18 -0500 | [diff] [blame] | 272 | public ApiInfo containingApi() { |
| 273 | return mContainingApi; |
| 274 | } |
| 275 | |
| 276 | public void setContainingApi(ApiInfo api) { |
| 277 | mContainingApi = api; |
| 278 | } |
| 279 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 280 | // in hashed containers, treat the name as the key |
| 281 | @Override |
| 282 | public int hashCode() { |
| 283 | return mName.hashCode(); |
| 284 | } |
| 285 | |
Hui Shu | 5118ffe | 2014-02-18 14:06:42 -0800 | [diff] [blame] | 286 | private Boolean mHidden = null; |
| 287 | private Boolean mHiddenByComment = null; |
| 288 | private Boolean mRemoved = null; |
| 289 | private Boolean mRemovedByComment = null; |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 290 | private String mName; |
| 291 | private PackageDoc mPackage; |
Mathieu | 11b1796 | 2013-06-07 17:24:18 -0500 | [diff] [blame] | 292 | private ApiInfo mContainingApi; |
Brett Chabot | 700b9f2 | 2013-10-04 16:57:39 -0700 | [diff] [blame] | 293 | private ClassInfo[] mAnnotations; |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 294 | private ClassInfo[] mInterfaces; |
| 295 | private ClassInfo[] mOrdinaryClasses; |
| 296 | private ClassInfo[] mEnums; |
| 297 | private ClassInfo[] mExceptions; |
| 298 | private ClassInfo[] mErrors; |
Scott Main | 3c1a6b2 | 2010-10-15 17:34:04 -0700 | [diff] [blame] | 299 | |
Brett Chabot | 700b9f2 | 2013-10-04 16:57:39 -0700 | [diff] [blame] | 300 | private HashMap<String, ClassInfo> mAnnotationsMap; |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 301 | private HashMap<String, ClassInfo> mInterfacesMap; |
| 302 | private HashMap<String, ClassInfo> mOrdinaryClassesMap; |
| 303 | private HashMap<String, ClassInfo> mEnumsMap; |
| 304 | private HashMap<String, ClassInfo> mExceptionsMap; |
| 305 | private HashMap<String, ClassInfo> mErrorsMap; |
| 306 | |
| 307 | |
| 308 | public ClassInfo getClass(String className) { |
| 309 | ClassInfo cls = mInterfacesMap.get(className); |
| 310 | |
| 311 | if (cls != null) { |
| 312 | return cls; |
| 313 | } |
| 314 | |
| 315 | cls = mOrdinaryClassesMap.get(className); |
| 316 | |
| 317 | if (cls != null) { |
| 318 | return cls; |
| 319 | } |
| 320 | |
| 321 | cls = mEnumsMap.get(className); |
| 322 | |
| 323 | if (cls != null) { |
| 324 | return cls; |
| 325 | } |
| 326 | |
| 327 | cls = mEnumsMap.get(className); |
| 328 | |
| 329 | if (cls != null) { |
| 330 | return cls; |
| 331 | } |
Brett Chabot | 700b9f2 | 2013-10-04 16:57:39 -0700 | [diff] [blame] | 332 | cls = mAnnotationsMap.get(className); |
| 333 | |
| 334 | if (cls != null) { |
| 335 | return cls; |
| 336 | } |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 337 | |
| 338 | return mErrorsMap.get(className); |
| 339 | } |
| 340 | |
Brett Chabot | 700b9f2 | 2013-10-04 16:57:39 -0700 | [diff] [blame] | 341 | public void addAnnotation(ClassInfo cls) { |
| 342 | cls.setPackage(this); |
| 343 | mAnnotationsMap.put(cls.name(), cls); |
| 344 | } |
| 345 | |
| 346 | public ClassInfo getAnnotation(String annotationName) { |
| 347 | return mAnnotationsMap.get(annotationName); |
| 348 | } |
| 349 | |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 350 | public void addInterface(ClassInfo cls) { |
Mathieu | 11b1796 | 2013-06-07 17:24:18 -0500 | [diff] [blame] | 351 | cls.setPackage(this); |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 352 | mInterfacesMap.put(cls.name(), cls); |
| 353 | } |
| 354 | |
| 355 | public ClassInfo getInterface(String interfaceName) { |
| 356 | return mInterfacesMap.get(interfaceName); |
| 357 | } |
| 358 | |
| 359 | public ClassInfo getOrdinaryClass(String className) { |
| 360 | return mOrdinaryClassesMap.get(className); |
| 361 | } |
| 362 | |
| 363 | public void addOrdinaryClass(ClassInfo cls) { |
Mathieu | 11b1796 | 2013-06-07 17:24:18 -0500 | [diff] [blame] | 364 | cls.setPackage(this); |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 365 | mOrdinaryClassesMap.put(cls.name(), cls); |
| 366 | } |
| 367 | |
| 368 | public ClassInfo getEnum(String enumName) { |
| 369 | return mEnumsMap.get(enumName); |
| 370 | } |
| 371 | |
| 372 | public void addEnum(ClassInfo cls) { |
Mathieu | 11b1796 | 2013-06-07 17:24:18 -0500 | [diff] [blame] | 373 | cls.setPackage(this); |
Andrew Sapperstein | d6eaacb | 2011-05-20 13:14:56 -0700 | [diff] [blame] | 374 | this.mEnumsMap.put(cls.name(), cls); |
| 375 | } |
| 376 | |
| 377 | public ClassInfo getException(String exceptionName) { |
| 378 | return mExceptionsMap.get(exceptionName); |
| 379 | } |
| 380 | |
| 381 | public ClassInfo getError(String errorName) { |
| 382 | return mErrorsMap.get(errorName); |
| 383 | } |
| 384 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 385 | // TODO: Leftovers from ApiCheck that should be better merged. |
| 386 | private HashMap<String, ClassInfo> mClasses = new HashMap<String, ClassInfo>(); |
Scott Main | 3c1a6b2 | 2010-10-15 17:34:04 -0700 | [diff] [blame] | 387 | |
Mathieu | 11b1796 | 2013-06-07 17:24:18 -0500 | [diff] [blame] | 388 | public void addClass(ClassInfo cls) { |
| 389 | cls.setPackage(this); |
| 390 | mClasses.put(cls.name(), cls); |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 391 | } |
| 392 | |
| 393 | public HashMap<String, ClassInfo> allClasses() { |
| 394 | return mClasses; |
| 395 | } |
Scott Main | 3c1a6b2 | 2010-10-15 17:34:04 -0700 | [diff] [blame] | 396 | |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 397 | public boolean isConsistent(PackageInfo pInfo) { |
Guang Zhu | f9b7c1b | 2015-04-24 16:45:42 -0700 | [diff] [blame^] | 398 | return isConsistent(pInfo, null); |
| 399 | } |
| 400 | |
| 401 | /** |
| 402 | * Creates the delta class by copying class signatures from original, but use provided list of |
| 403 | * constructors and methods. |
| 404 | */ |
| 405 | private ClassInfo createDeltaClass(ClassInfo original, |
| 406 | ArrayList<MethodInfo> constructors, ArrayList<MethodInfo> methods) { |
| 407 | ArrayList<FieldInfo> emptyFields = new ArrayList<>(); |
| 408 | ArrayList<ClassInfo> emptyClasses = new ArrayList<>(); |
| 409 | ArrayList<TypeInfo> emptyTypes = new ArrayList<>(); |
| 410 | ArrayList<MethodInfo> emptyMethods = new ArrayList<>(); |
| 411 | ClassInfo ret = new ClassInfo(null, original.getRawCommentText(), original.position(), |
| 412 | original.isPublic(), original.isProtected(), original.isPackagePrivate(), |
| 413 | original.isPrivate(), original.isStatic(), original.isInterface(), |
| 414 | original.isAbstract(), original.isOrdinaryClass(), |
| 415 | original.isException(), original.isError(), original.isEnum(), original.isAnnotation(), |
| 416 | original.isFinal(), original.isIncluded(), original.name(), original.qualifiedName(), |
| 417 | original.qualifiedTypeName(), original.isPrimitive()); |
| 418 | ArrayList<ClassInfo> interfaces = original.interfaces(); |
| 419 | // avoid providing null to init method, replace with empty array list when needed |
| 420 | if (interfaces == null) { |
| 421 | interfaces = emptyClasses; |
| 422 | } |
| 423 | ArrayList<TypeInfo> interfaceTypes = original.interfaceTypes(); |
| 424 | if (interfaceTypes == null) { |
| 425 | interfaceTypes = emptyTypes; |
| 426 | } |
| 427 | ArrayList<ClassInfo> innerClasses = original.innerClasses(); |
| 428 | if (innerClasses == null) { |
| 429 | innerClasses = emptyClasses; |
| 430 | } |
| 431 | ArrayList<MethodInfo> annotationElements = original.annotationElements(); |
| 432 | if (annotationElements == null) { |
| 433 | annotationElements = emptyMethods; |
| 434 | } |
| 435 | ArrayList<AnnotationInstanceInfo> annotations = original.annotations(); |
| 436 | if (annotations == null) { |
| 437 | annotations = new ArrayList<>(); |
| 438 | } |
| 439 | ret.init(original.type(), interfaces, interfaceTypes, innerClasses, |
| 440 | constructors, methods, annotationElements, |
| 441 | emptyFields /* fields */, emptyFields /* enum */, |
| 442 | original.containingPackage(), original.containingClass(), original.superclass(), |
| 443 | original.superclassType(), annotations); |
| 444 | return ret; |
| 445 | } |
| 446 | |
| 447 | /** |
| 448 | * Check if packages are consistent, also record class deltas. |
| 449 | * <p> |
| 450 | * <ul>class deltas are: |
| 451 | * <li>brand new classes that are not present in current package |
| 452 | * <li>stripped existing classes stripped where only newly added methods are kept |
| 453 | * @param pInfo |
| 454 | * @param clsInfoDiff |
| 455 | * @return |
| 456 | */ |
| 457 | public boolean isConsistent(PackageInfo pInfo, List<ClassInfo> clsInfoDiff) { |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 458 | boolean consistent = true; |
Guang Zhu | f9b7c1b | 2015-04-24 16:45:42 -0700 | [diff] [blame^] | 459 | boolean diffMode = clsInfoDiff != null; |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 460 | for (ClassInfo cInfo : mClasses.values()) { |
Guang Zhu | f9b7c1b | 2015-04-24 16:45:42 -0700 | [diff] [blame^] | 461 | ArrayList<MethodInfo> newClsApis = null; |
| 462 | ArrayList<MethodInfo> newClsCtors = null; |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 463 | if (pInfo.mClasses.containsKey(cInfo.name())) { |
Guang Zhu | f9b7c1b | 2015-04-24 16:45:42 -0700 | [diff] [blame^] | 464 | if (diffMode) { |
| 465 | newClsApis = new ArrayList<>(); |
| 466 | newClsCtors = new ArrayList<>(); |
| 467 | } |
| 468 | if (!cInfo.isConsistent(pInfo.mClasses.get(cInfo.name()), newClsCtors, newClsApis)) { |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 469 | consistent = false; |
| 470 | } |
Guang Zhu | f9b7c1b | 2015-04-24 16:45:42 -0700 | [diff] [blame^] | 471 | // if we are in diff mode, add class to list if there's new ctor or new apis |
| 472 | if (diffMode && !(newClsCtors.isEmpty() && newClsApis.isEmpty())) { |
| 473 | // generate a "delta" class with only added methods and constructors, but no fields etc |
| 474 | ClassInfo deltaClsInfo = createDeltaClass(cInfo, newClsCtors, newClsApis); |
| 475 | clsInfoDiff.add(deltaClsInfo); |
| 476 | } |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 477 | } else { |
| 478 | Errors.error(Errors.REMOVED_CLASS, cInfo.position(), "Removed public class " |
| 479 | + cInfo.qualifiedName()); |
| 480 | consistent = false; |
| 481 | } |
| 482 | } |
| 483 | for (ClassInfo cInfo : pInfo.mClasses.values()) { |
| 484 | if (!mClasses.containsKey(cInfo.name())) { |
| 485 | Errors.error(Errors.ADDED_CLASS, cInfo.position(), "Added class " + cInfo.name() |
| 486 | + " to package " + pInfo.name()); |
| 487 | consistent = false; |
Guang Zhu | f9b7c1b | 2015-04-24 16:45:42 -0700 | [diff] [blame^] | 488 | // brand new class, add everything as is |
| 489 | if (diffMode) { |
| 490 | clsInfoDiff.add(cInfo); |
| 491 | } |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 492 | } |
| 493 | } |
Guang Zhu | f9b7c1b | 2015-04-24 16:45:42 -0700 | [diff] [blame^] | 494 | if (diffMode) { |
| 495 | Collections.sort(clsInfoDiff, ClassInfo.comparator); |
| 496 | } |
Ben Dodson | 920dbbb | 2010-08-04 15:21:06 -0700 | [diff] [blame] | 497 | return consistent; |
| 498 | } |
| 499 | } |