1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.jdeprscan; 27 28 import java.io.BufferedReader; 29 import java.io.IOException; 30 import java.nio.file.Files; 31 import java.nio.file.Paths; 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.Formatter; 35 import java.util.HashMap; 36 import java.util.List; 37 import java.util.Locale; 38 import java.util.Map; 39 import java.util.Set; 40 41 import javax.lang.model.element.ElementKind; 42 43 /** 44 * A database of deprecations (APIs declared to be deprecated), 45 * loaded from a JDK or from a class library. 46 */ 47 public class DeprDB { 48 /** 49 * Deprecated types. 50 * A map from deprecated type names to DeprData values. 51 * Types include classes, interfaces, enums, and annotation types. 52 */ 53 final Map<String, DeprData> types = new HashMap<>(); 54 55 /** 56 * Deprecated methods. Key is type name, value is map from method 57 * signatures in the form "methodname(parms)ret" to DeprData value. 58 */ 59 final Map<String, Map<String, DeprData>> methods = new HashMap<>(); 60 61 /** 62 * Deprecated fields. Key is type name, value is map from field name 63 * to forRemoval value. 64 */ 65 final Map<String, Map<String, DeprData>> fields = new HashMap<>(); 66 67 /** 68 * Set of valid ElementKind strings. 69 */ 70 static final Set<String> validElementKinds = 71 Set.of(Arrays.stream(ElementKind.values()) 72 .map(ElementKind::toString) 73 .toArray(String[]::new)); 74 75 76 private DeprDB() { } 77 78 public static List<DeprData> loadFromFile(String filename) throws IOException { 79 List<DeprData> list = new ArrayList<>(); 80 81 exit: 82 try (final BufferedReader br = Files.newBufferedReader(Paths.get(filename))) { 83 String line = br.readLine(); 84 if (line == null || !line.equals("#jdepr1")) { 85 System.out.printf("ERROR: invalid first line %s%n", line); 86 break exit; 87 } 88 while ((line = br.readLine()) != null) { 89 if (line.startsWith("#")) { 90 continue; 91 } 92 List<String> tokens = CSV.split(line); 93 if (tokens.size() != 5) { 94 System.out.printf("ERROR: %s%n", line); 95 continue; 96 } 97 // kind,typeName,descOrName,since,forRemoval 98 String kindStr = tokens.get(0); 99 String type = tokens.get(1); 100 String detail = tokens.get(2); 101 String since = tokens.get(3); 102 boolean forRemoval = Boolean.parseBoolean(tokens.get(4)); 103 ElementKind kind; 104 105 if (validElementKinds.contains(kindStr)) { 106 kind = ElementKind.valueOf(kindStr); 107 } else { 108 System.out.printf("ERROR: invalid element kind %s%n", kindStr); 109 continue; 110 } 111 112 DeprData data = new DeprData(kind, /*TypeElement*/null, type, detail, since, forRemoval); 113 list.add(data); 114 } 115 } 116 return list; 117 } 118 119 public static DeprDB loadFromList(List<DeprData> deprList) { 120 DeprDB db = new DeprDB(); 121 122 for (DeprData dd : deprList) { 123 switch (dd.kind) { 124 case CLASS: 125 case INTERFACE: 126 case ENUM: 127 case ANNOTATION_TYPE: 128 db.types.put(dd.typeName, dd); 129 break; 130 case METHOD: 131 case CONSTRUCTOR: 132 db.methods.computeIfAbsent(dd.typeName, k -> new HashMap<>()) 133 .put(dd.nameSig, dd); 134 break; 135 case ENUM_CONSTANT: 136 case FIELD: 137 db.fields.computeIfAbsent(dd.typeName, k -> new HashMap<>()) 138 .put(dd.nameSig, dd); 139 break; 140 } 141 } 142 143 return db; 144 } 145 146 @Override 147 public String toString() { 148 StringBuilder sb = new StringBuilder(); 149 Formatter f = new Formatter(sb, Locale.US); 150 f.format("=== Types ===%n"); 151 f.format("%s%n", types.toString()); 152 f.format("=== Methods ===%n"); 153 f.format("%s%n", methods.toString()); 154 f.format("=== Fields ===%n"); 155 f.format("%s%n", fields.toString()); 156 return sb.toString(); 157 } 158 159 public DeprData getTypeDeprecated(String typeName) { 160 return types.get(typeName); 161 } 162 163 public DeprData getMethodDeprecated(String typeName, String methodName, String type) { 164 Map<String, DeprData> m = methods.get(typeName); 165 if (m == null) { 166 return null; 167 } 168 return m.get(methodName + type); 169 } 170 171 public DeprData getFieldDeprecated(String typeName, String fieldName) { 172 Map<String, DeprData> f = fields.get(typeName); 173 if (f == null) { 174 return null; 175 } 176 return f.get(fieldName); 177 } 178 }