1 19 20 package org.netbeans.modules.java.source.usages; 21 22 import java.util.ArrayList ; 23 import java.util.Arrays ; 24 import java.util.Collections ; 25 import java.util.List ; 26 import java.util.Set ; 27 import javax.lang.model.element.ElementKind; 28 import org.apache.lucene.document.DateTools; 29 import org.apache.lucene.document.Document; 30 import org.apache.lucene.document.Field; 31 import org.apache.lucene.index.Term; 32 import org.apache.lucene.search.BooleanClause; 33 import org.apache.lucene.search.BooleanQuery; 34 import org.apache.lucene.search.PrefixQuery; 35 import org.apache.lucene.search.Query; 36 import org.apache.lucene.search.TermQuery; 37 import org.apache.lucene.search.WildcardQuery; 38 39 43 class DocumentUtil { 44 45 private static final String ROOT_NAME="/"; private static final String FIELD_RESOURCE_NAME = "resName"; private static final String FIELD_BINARY_NAME = "binaryName"; private static final String FIELD_PACKAGE_NAME = "packageName"; private static final String FIELD_TIME_STAMP = "timeStamp"; private static final String FIELD_REFERENCES = "references"; private static final String FIELD_SIMPLE_NAME = "simpleName"; private static final String FIELD_CASE_INSENSITIVE_NAME = "ciName"; 54 private static final char NO = '-'; private static final char YES = '+'; private static final char WILDCARD = '?'; private static final char PKG_SEPARATOR = '.'; 59 private static final char EK_CLASS = 'C'; private static final char EK_INTERFACE = 'I'; private static final char EK_ENUM = 'E'; private static final char EK_ANNOTATION = 'A'; 64 private static final int SIZE = ClassIndexImpl.UsageType.values().length; 65 private static final char[] MASK_ANY_USAGE = new char[SIZE]; 66 67 static { 68 Arrays.fill(MASK_ANY_USAGE, WILDCARD); } 70 71 private DocumentUtil () { 72 } 73 74 75 public static String getBinaryName (final Document doc) { 77 return getBinaryName(doc, null); 78 } 79 80 public static String getBinaryName (final Document doc, final ElementKind[] kind) { 81 assert doc != null; 82 final Field pkgField = doc.getField(FIELD_PACKAGE_NAME); 83 final Field snField = doc.getField (FIELD_BINARY_NAME); 84 if (snField == null) { 85 return null; 86 } 87 final String tmp = snField.stringValue(); 88 final String snName = tmp.substring(0,tmp.length()-1); 89 if (kind != null) { 90 assert kind.length == 1; 91 kind[0] = decodeKind (tmp.charAt(tmp.length()-1)); 92 } 93 if (pkgField == null) { 94 return snName; 95 } 96 String pkg = pkgField.stringValue(); 97 if (pkg.length() == 0) { 98 return snName; 99 } 100 return pkg + PKG_SEPARATOR + snName; } 102 103 public static String getSimpleBinaryName (final Document doc) { 104 assert doc != null; 105 Field field = doc.getField(FIELD_BINARY_NAME); 106 if (field == null) { 107 return null; 108 } 109 else { 110 return field.stringValue(); 111 } 112 } 113 114 public static String getPackageName (final Document doc) { 115 assert doc != null; 116 Field field = doc.getField(FIELD_PACKAGE_NAME); 117 return field == null ? null : field.stringValue(); 118 } 119 120 static String getRefereneType (final Document doc, final String className) { 121 assert doc != null; 122 assert className != null; 123 Field[] fields = doc.getFields(FIELD_REFERENCES); 124 assert fields != null; 125 for (Field field : fields) { 126 final String rawUsage = field.stringValue(); 127 final int rawUsageLen = rawUsage.length(); 128 assert rawUsageLen>SIZE; 129 final int index = rawUsageLen - SIZE; 130 final String usageName = rawUsage.substring(0,index); 131 final String map = rawUsage.substring (index); 132 if (className.equals(usageName)) { 133 return map; 134 } 135 } 136 return null; 137 } 138 139 public static List <String > getReferences (final Document doc) { 140 assert doc != null; 141 Field[] fields = doc.getFields(FIELD_REFERENCES); 142 assert fields != null; 143 List <String > result = new ArrayList <String > (fields.length); 144 for (Field field : fields) { 145 result.add (field.stringValue()); 146 } 147 return result; 148 } 149 150 public static long getTimeStamp (final Document doc) throws java.text.ParseException { 151 assert doc != null; 152 Field field = doc.getField(FIELD_TIME_STAMP); 153 assert field != null; 154 String data = field.stringValue(); 155 assert data != null; 156 return DateTools.stringToTime(data); 157 } 158 159 160 public static Query binaryNameQuery (final String resourceName) { 162 BooleanQuery query = new BooleanQuery (); 163 int index = resourceName.lastIndexOf(PKG_SEPARATOR); String pkgName, sName; 165 if (index < 0) { 166 pkgName = ""; sName = resourceName; 168 } 169 else { 170 pkgName = resourceName.substring(0,index); 171 sName = resourceName.substring(index+1); 172 } 173 sName = sName + WILDCARD; 174 query.add (new TermQuery (new Term (FIELD_PACKAGE_NAME, pkgName)),BooleanClause.Occur.MUST); 175 query.add (new WildcardQuery (new Term (FIELD_BINARY_NAME, sName)),BooleanClause.Occur.MUST); 176 return query; 177 } 178 179 public static Query binaryContentNameQuery (final String resourceName) { 180 int index = resourceName.lastIndexOf(PKG_SEPARATOR); String pkgName, sName; 182 if (index < 0) { 183 pkgName = ""; sName = resourceName; 185 } 186 else { 187 pkgName = resourceName.substring(0,index); 188 sName = resourceName.substring(index+1); 189 } 190 BooleanQuery query = new BooleanQuery (); 191 BooleanQuery subQuery = new BooleanQuery(); 192 subQuery.add (new WildcardQuery (new Term (FIELD_BINARY_NAME, sName + WILDCARD)),BooleanClause.Occur.SHOULD); 193 subQuery.add (new PrefixQuery (new Term (FIELD_BINARY_NAME, sName + '$')),BooleanClause.Occur.SHOULD); 194 query.add (new TermQuery (new Term (FIELD_PACKAGE_NAME, pkgName)),BooleanClause.Occur.MUST); 195 query.add (subQuery,BooleanClause.Occur.MUST); 196 return query; 197 } 198 199 200 public static Term rootDocumentTerm () { 201 return new Term (FIELD_RESOURCE_NAME,ROOT_NAME); 202 } 203 204 public static Term simpleBinaryNameTerm (final String resourceFileName) { 205 assert resourceFileName != null; 206 return new Term (FIELD_BINARY_NAME, resourceFileName); 207 } 208 209 public static Term packageNameTerm (final String packageName) { 210 assert packageName != null; 211 return new Term (FIELD_PACKAGE_NAME, packageName); 212 } 213 214 public static Term referencesTerm (String resourceName, final Set <ClassIndexImpl.UsageType> usageType) { 215 assert resourceName != null; 216 if (usageType != null) { 217 resourceName = encodeUsage (resourceName, usageType, WILDCARD).toString(); 218 } 219 else { 220 StringBuilder sb = new StringBuilder (resourceName); 221 sb.append(MASK_ANY_USAGE); 222 resourceName = sb.toString(); 223 } 224 return new Term (FIELD_REFERENCES, resourceName); 225 } 226 227 public static Term simpleNameTerm (final String resourceSimpleName) { 228 assert resourceSimpleName != null; 229 return new Term (FIELD_SIMPLE_NAME, resourceSimpleName); 230 } 231 232 public static Term caseInsensitiveNameTerm (final String caseInsensitiveName) { 233 assert caseInsensitiveName != null; 234 return new Term (FIELD_CASE_INSENSITIVE_NAME, caseInsensitiveName); 235 } 236 237 public static Document createDocument (final String binaryName, final long timeStamp, List <String > references) { 239 assert binaryName != null; 240 assert references != null; 241 int index = binaryName.lastIndexOf(PKG_SEPARATOR); String fileName, pkgName, simpleName, caseInsensitiveName; 243 if (index<0) { 244 fileName = binaryName; 245 pkgName = ""; } 247 else { 248 fileName = binaryName.substring(index+1); 249 pkgName = binaryName.substring(0,index); 250 } 251 index = fileName.lastIndexOf('$'); if (index<0) { 253 simpleName = fileName.substring(0, fileName.length()-1); 254 } 255 else { 256 simpleName = fileName.substring(index+1,fileName.length()-1); 257 } 258 caseInsensitiveName = simpleName.toLowerCase(); Document doc = new Document (); 260 Field field = new Field (FIELD_BINARY_NAME,fileName,Field.Store.YES, Field.Index.UN_TOKENIZED); 261 doc.add (field); 262 field = new Field (FIELD_PACKAGE_NAME,pkgName,Field.Store.YES, Field.Index.UN_TOKENIZED); 263 doc.add (field); 264 field = new Field (FIELD_TIME_STAMP,DateTools.timeToString(timeStamp,DateTools.Resolution.MILLISECOND),Field.Store.YES,Field.Index.NO); 265 doc.add (field); 266 field = new Field (FIELD_SIMPLE_NAME,simpleName, Field.Store.YES, Field.Index.UN_TOKENIZED); 267 doc.add (field); 268 field = new Field (FIELD_CASE_INSENSITIVE_NAME, caseInsensitiveName, Field.Store.YES, Field.Index.UN_TOKENIZED); 269 doc.add (field); 270 for (String reference : references) { 271 field = new Field (FIELD_REFERENCES,reference,Field.Store.YES,Field.Index.UN_TOKENIZED); 272 doc.add(field); 273 } 274 return doc; 275 } 276 277 public static Document createRootTimeStampDocument (final long timeStamp) { 278 Document doc = new Document (); 279 Field field = new Field (FIELD_RESOURCE_NAME, ROOT_NAME,Field.Store.YES, Field.Index.UN_TOKENIZED); 280 doc.add (field); 281 field = new Field (FIELD_TIME_STAMP,DateTools.timeToString(timeStamp,DateTools.Resolution.MILLISECOND),Field.Store.YES,Field.Index.NO); 282 doc.add (field); 283 return doc; 284 } 285 286 public static StringBuilder createUsage (final String className) { 288 Set <ClassIndexImpl.UsageType> EMPTY = Collections.emptySet(); 289 return encodeUsage (className, EMPTY,NO); 290 } 291 292 public static void addUsage (final StringBuilder rawUsage, final ClassIndexImpl.UsageType type) { 293 assert rawUsage != null; 294 assert type != null; 295 final int rawUsageLen = rawUsage.length(); 296 final int startIndex = rawUsageLen - SIZE; 297 rawUsage.setCharAt (startIndex + type.getOffset(),YES); 298 } 299 300 public static String encodeUsage (final String className, final Set <ClassIndexImpl.UsageType> usageTypes) { 301 return encodeUsage (className, usageTypes, NO).toString(); 302 } 303 304 private static StringBuilder encodeUsage (final String className, final Set <ClassIndexImpl.UsageType> usageTypes, char fill) { 305 assert className != null; 306 assert usageTypes != null; 307 StringBuilder builder = new StringBuilder (); 308 builder.append(className); 309 char[] map = new char [SIZE]; 310 Arrays.fill(map,fill); 311 for (ClassIndexImpl.UsageType usageType : usageTypes) { 312 int offset = usageType.getOffset (); 313 assert offset >= 0 && offset < SIZE; 314 map[offset] = YES; 315 } 316 builder.append(map); 317 return builder; 318 } 319 320 public static String encodeUsage (final String className, final String usageMap) { 321 assert className != null; 322 assert usageMap != null; 323 StringBuilder sb = new StringBuilder (); 324 sb.append(className); 325 sb.append(usageMap); 326 return sb.toString(); 327 } 328 329 public static String decodeUsage (final String rawUsage, final Set <ClassIndexImpl.UsageType> usageTypes) { 330 assert rawUsage != null; 331 assert usageTypes != null; 332 assert usageTypes.isEmpty(); 333 final int rawUsageLen = rawUsage.length(); 334 assert rawUsageLen>SIZE; 335 final int index = rawUsageLen - SIZE; 336 final String className = rawUsage.substring(0,index); 337 final String map = rawUsage.substring (index); 338 for (ClassIndexImpl.UsageType usageType : ClassIndexImpl.UsageType.values()) { 339 if (map.charAt(usageType.getOffset()) == YES) { 340 usageTypes.add (usageType); 341 } 342 } 343 return className; 344 } 345 346 public static ElementKind decodeKind (char kind) { 347 switch (kind) { 348 case EK_CLASS: 349 return ElementKind.CLASS; 350 case EK_INTERFACE: 351 return ElementKind.INTERFACE; 352 case EK_ENUM: 353 return ElementKind.ENUM; 354 case EK_ANNOTATION: 355 return ElementKind.ANNOTATION_TYPE; 356 default: 357 throw new IllegalArgumentException (); 358 } 359 } 360 361 public static char encodeKind (ElementKind kind) { 362 switch (kind) { 363 case CLASS: 364 return EK_CLASS; 365 case INTERFACE: 366 return EK_INTERFACE; 367 case ENUM: 368 return EK_ENUM; 369 case ANNOTATION_TYPE: 370 return EK_ANNOTATION; 371 default: 372 throw new IllegalArgumentException (); 373 } 374 } 375 376 377 } 378 | Popular Tags |