All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.org.eclipse.jdt.internal.core.index.Index Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.core.index;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.core.search.*;
import org.aspectj.org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
import org.aspectj.org.eclipse.jdt.internal.compiler.util.SimpleSet;
import org.aspectj.org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
import org.aspectj.org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor;

/**
 * An Index maps document names to their referenced words in various categories.
 * 

* Queries can search a single category or several at the same time. *

* Indexes are not synchronized structures and should only be queried/updated one at a time. */ public class Index { public String containerPath; public volatile ReadWriteMonitor monitor; // Separator to use after the container path static final char DEFAULT_SEPARATOR = '/'; public char separator = DEFAULT_SEPARATOR; static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0); protected DiskIndex diskIndex; protected MemoryIndex memoryIndex; /** * Mask used on match rule for indexing. */ static final int MATCH_RULE_INDEX_MASK = SearchPattern.R_EXACT_MATCH | SearchPattern.R_PREFIX_MATCH | SearchPattern.R_PATTERN_MATCH | SearchPattern.R_REGEXP_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_SUBSTRING_MATCH | SearchPattern.R_SUBWORD_MATCH; public static boolean isMatch(char[] pattern, char[] word, int matchRule) { if (pattern == null) return true; int patternLength = pattern.length; int wordLength = word.length; if (patternLength == 0) return matchRule != SearchPattern.R_EXACT_MATCH; if (wordLength == 0) return (matchRule & SearchPattern.R_PATTERN_MATCH) != 0 && patternLength == 1 && pattern[0] == '*'; if ((matchRule & SearchPattern.R_SUBSTRING_MATCH) != 0) { if (CharOperation.substringMatch(pattern, word)) return true; matchRule &= ~SearchPattern.R_SUBSTRING_MATCH; } if ((matchRule & SearchPattern.R_SUBWORD_MATCH) != 0) { if (CharOperation.subWordMatch(pattern, word)) return true; matchRule &= ~SearchPattern.R_SUBWORD_MATCH; } // need to mask some bits of pattern rule (bug 79790) switch(matchRule & MATCH_RULE_INDEX_MASK) { case SearchPattern.R_EXACT_MATCH : return patternLength == wordLength && CharOperation.equals(pattern, word, false); case SearchPattern.R_PREFIX_MATCH : return patternLength <= wordLength && CharOperation.prefixEquals(pattern, word, false); case SearchPattern.R_REGEXP_MATCH : Pattern regexPattern = Pattern.compile(new String(pattern)); return regexPattern.matcher(new String(word)).matches(); case SearchPattern.R_PATTERN_MATCH : return CharOperation.match(pattern, word, false); case SearchPattern.R_CAMELCASE_MATCH: // same part count is not activated because index key may have uppercase letters after the type name case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH: if (CharOperation.camelCaseMatch(pattern, word, false)) { return true; } return patternLength <= wordLength && CharOperation.prefixEquals(pattern, word, false); case SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE : return pattern[0] == word[0] && patternLength == wordLength && CharOperation.equals(pattern, word); case SearchPattern.R_PREFIX_MATCH | SearchPattern.R_CASE_SENSITIVE : return pattern[0] == word[0] && patternLength <= wordLength && CharOperation.prefixEquals(pattern, word); case SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE : return CharOperation.match(pattern, word, true); case SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_CASE_SENSITIVE : // same part count is not activated because index key may have uppercase letters after the type name case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_CASE_SENSITIVE : return (pattern[0] == word[0] && CharOperation.camelCaseMatch(pattern, word, false)); } return false; } public Index(IndexLocation location, String containerPath, boolean reuseExistingFile) throws IOException { this.containerPath = containerPath; this.monitor = new ReadWriteMonitor(); this.memoryIndex = new MemoryIndex(); this.diskIndex = new DiskIndex(location); this.diskIndex.initialize(reuseExistingFile); if (reuseExistingFile) this.separator = this.diskIndex.separator; } public void addIndexEntry(char[] category, char[] key, String containerRelativePath) { this.memoryIndex.addIndexEntry(category, key, containerRelativePath); } public String containerRelativePath(String documentPath) { int index = documentPath.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR); if (index == -1) { index = this.containerPath.length(); if (documentPath.length() <= index) throw new IllegalArgumentException("Document path " + documentPath + " must be relative to " + this.containerPath); //$NON-NLS-1$ //$NON-NLS-2$ } return documentPath.substring(index + 1); } public File getIndexFile() { return this.diskIndex == null ? null : this.diskIndex.indexLocation.getIndexFile(); } public IndexLocation getIndexLocation() { return this.diskIndex == null ? null : this.diskIndex.indexLocation; } public long getIndexLastModified() { return this.diskIndex == null? -1 : this.diskIndex.indexLocation.lastModified(); } public boolean hasChanged() { return this.memoryIndex.hasChanged(); } /** * Returns the entries containing the given key in a group of categories, or null if no matches are found. * The matchRule dictates whether its an exact, prefix or pattern match, as well as case sensitive or insensitive. * If the key is null then all entries in specified categories are returned. */ public EntryResult[] query(char[][] categories, char[] key, int matchRule) throws IOException { ReadWriteMonitor readWriteMonitor = this.monitor; if(readWriteMonitor == null) { // index got deleted since acquired return null; } if (this.memoryIndex.shouldMerge() && readWriteMonitor.exitReadEnterWrite()) { try { save(); } finally { readWriteMonitor.exitWriteEnterRead(); } } HashtableOfObject results; int rule = matchRule & MATCH_RULE_INDEX_MASK; if (this.memoryIndex.hasChanged()) { results = this.diskIndex.addQueryResults(categories, key, rule, this.memoryIndex); results = this.memoryIndex.addQueryResults(categories, key, rule, results); } else { results = this.diskIndex.addQueryResults(categories, key, rule, null); } if (results == null) return null; EntryResult[] entryResults = new EntryResult[results.elementSize]; int count = 0; Object[] values = results.valueTable; for (int i = 0, l = values.length; i < l; i++) { EntryResult result = (EntryResult) values[i]; if (result != null) entryResults[count++] = result; } return entryResults; } /** * Returns the document names that contain the given substring, if null then returns all of them. */ public String[] queryDocumentNames(String substring) throws IOException { SimpleSet results; if (this.memoryIndex.hasChanged()) { results = this.diskIndex.addDocumentNames(substring, this.memoryIndex); this.memoryIndex.addDocumentNames(substring, results); } else { results = this.diskIndex.addDocumentNames(substring, null); } if (results.elementSize == 0) return null; String[] documentNames = new String[results.elementSize]; int count = 0; Object[] paths = results.values; for (int i = 0, l = paths.length; i < l; i++) if (paths[i] != null) documentNames[count++] = (String) paths[i]; return documentNames; } public void remove(String containerRelativePath) { this.memoryIndex.remove(containerRelativePath); } /** * Reset memory and disk indexes. */ public void reset() throws IOException { this.memoryIndex = new MemoryIndex(); this.diskIndex = new DiskIndex(this.diskIndex.indexLocation); this.diskIndex.initialize(false/*do not reuse the index file*/); } public boolean save() throws IOException { ReadWriteMonitor readWriteMonitor = this.monitor; if(readWriteMonitor == null) { // index got deleted since acquired return false; } // must own the write lock of the monitor if (!hasChanged()) return false; this.diskIndex.separator = this.separator; this.diskIndex = this.diskIndex.mergeWith(this.memoryIndex); this.memoryIndex = new MemoryIndex(); return true; } public void startQuery() { if (this.diskIndex != null) this.diskIndex.startQuery(); } public void stopQuery() { if (this.diskIndex != null) this.diskIndex.stopQuery(); } @Override public String toString() { return "Index for " + this.containerPath; //$NON-NLS-1$ } public boolean isIndexForJar() { return this.separator == JAR_SEPARATOR; } public List getMetaIndexQualifications() throws IOException { startQuery(); try { ArrayList qualifiers = new ArrayList<>(); for(char[] category : IIndexConstants.META_INDEX_CATEGORIES) { if (this.monitor == null) { // index got deleted since acquired return Collections.emptyList(); } EntryResult[] results = query(new char[][] {category}, null, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE); if(results != null) { qualifiers.ensureCapacity(results.length); // minimize array resize for (int i = 0; i < results.length; i++) { qualifiers.add(IndexQualifier.qualifier(category, results[i].getWord())); } } } return qualifiers; } finally { stopQuery(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy