package org.eclipse.jdt.internal.core.nd.java;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.NdNode;
import org.eclipse.jdt.internal.core.nd.db.Database;
import org.eclipse.jdt.internal.core.nd.db.IString;
import org.eclipse.jdt.internal.core.nd.db.IndexException;
import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldLong;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany.Visitor;
import org.eclipse.jdt.internal.core.nd.field.FieldSearchIndex.IResultRank;
import org.eclipse.jdt.internal.core.nd.field.FieldSearchIndex.SearchCriteria;
import org.eclipse.jdt.internal.core.nd.field.FieldSearchKey;
import org.eclipse.jdt.internal.core.nd.field.FieldShort;
import org.eclipse.jdt.internal.core.nd.field.FieldString;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
public class NdResourceFile extends NdNode {
public static final FieldSearchKey<JavaIndex> FILENAME;
public static final FieldOneToMany<NdType> TYPES;
public static final FieldLong TIME_LAST_USED;
public static final FieldLong TIME_LAST_SCANNED;
public static final FieldLong SIZE_LAST_SCANNED;
public static final FieldLong HASHCODE_LAST_SCANNED;
public static final FieldOneToMany<NdWorkspaceLocation> WORKSPACE_MAPPINGS;
public static final FieldString JAVA_ROOT;
public static final FieldLong JDK_LEVEL;
public static final FieldList<NdZipEntry> ZIP_ENTRIES;
public static final FieldString MANIFEST_CONTENT;
public static final FieldShort FILE_FLAGS;
public static final int FLG_CORRUPT_ZIP_FILE = 0x0001;
@SuppressWarnings("hiding")
public static final StructDef<NdResourceFile> type;
static {
type = StructDef.create(NdResourceFile.class, NdNode.type);
FILENAME = FieldSearchKey.create(type, JavaIndex.FILES);
TYPES = FieldOneToMany.create(type, NdType.FILE, 16);
TIME_LAST_USED = type.addLong();
TIME_LAST_SCANNED = type.addLong();
SIZE_LAST_SCANNED = type.addLong();
HASHCODE_LAST_SCANNED = type.addLong();
WORKSPACE_MAPPINGS = FieldOneToMany.create(type, NdWorkspaceLocation.RESOURCE);
JAVA_ROOT = type.addString();
JDK_LEVEL = type.addLong();
ZIP_ENTRIES = FieldList.create(type, NdZipEntry.type, 1);
MANIFEST_CONTENT = type.addString();
FILE_FLAGS = type.addShort();
type.done();
}
private long jdkLevel;
public NdResourceFile(Nd dom, long address) {
super(dom, address);
}
public NdResourceFile(Nd nd) {
super(nd);
}
public boolean isCorruptedZipFile() {
return hasAllFlags(FLG_CORRUPT_ZIP_FILE);
}
public int getFlags() {
return FILE_FLAGS.get(getNd(), this.address);
}
public boolean hasAllFlags(int flags) {
int ourFlags = getFlags();
return (ourFlags & flags) == flags;
}
public void setFlags(int flags) {
FILE_FLAGS.put(getNd(), this.address, (short) (getFlags() | flags));
}
public List<NdZipEntry> getZipEntries() {
return ZIP_ENTRIES.asList(getNd(), getAddress());
}
public IString getManifestContent() {
return MANIFEST_CONTENT.get(getNd(), getAddress());
}
public void setManifestContent(char[] newContent) {
MANIFEST_CONTENT.put(getNd(), getAddress(), newContent);
}
public long getJdkLevel() {
if (this.jdkLevel == 0) {
this.jdkLevel = JDK_LEVEL.get(getNd(), this.address);
}
return this.jdkLevel;
}
public void setJdkLevel(long jdkLevel) {
if (getJdkLevel() != jdkLevel) {
JDK_LEVEL.put(getNd(), this.address, jdkLevel);
}
}
public boolean isInIndex() {
try {
if (!this.nd.isValidAddress(this.address)
|| NODE_TYPE.get(this.nd, this.address) != this.nd.getNodeType(getClass())) {
return false;
}
char[] filename = FILENAME.get(getNd(), this.address).getChars();
NdResourceFile result = JavaIndex.FILES.findBest(this.nd, Database.DATA_AREA_OFFSET,
SearchCriteria.create(filename), new IResultRank() {
@Override
public long getRank(Nd testNd, long testAddress) {
if (testAddress == NdResourceFile.this.address) {
return 1;
}
return -1;
}
});
return (this.equals(result));
} catch (IndexException e) {
return false;
}
}
public List<IPath> getAllWorkspaceLocations() {
final List<IPath> result = new ArrayList<>();
WORKSPACE_MAPPINGS.accept(getNd(), this.address, new Visitor<NdWorkspaceLocation>() {
@Override
public void visit(int index, NdWorkspaceLocation toVisit) {
result.add(new Path(toVisit.getPath().getString()));
}
});
return result;
}
public IPath getFirstWorkspaceLocation() {
if (WORKSPACE_MAPPINGS.isEmpty(getNd(), this.address)) {
return Path.EMPTY;
}
return new Path(WORKSPACE_MAPPINGS.get(getNd(), this.address, 0).getPath().toString());
}
public IPath getAnyOpenWorkspaceLocation(IWorkspaceRoot root) {
int numMappings = WORKSPACE_MAPPINGS.size(getNd(), this.address);
for (int mapping = 0; mapping < numMappings; mapping++) {
NdWorkspaceLocation nextMapping = WORKSPACE_MAPPINGS.get(getNd(), this.address, mapping);
IPath nextPath = new Path(nextMapping.getPath().getString());
if (nextPath.isEmpty()) {
continue;
}
IProject project = root.getProject(nextPath.segment(0));
if (project.isOpen()) {
return nextPath;
}
}
return Path.EMPTY;
}
public IPath getPath() {
IPath workspacePath = getFirstWorkspaceLocation();
if (workspacePath.isEmpty()) {
return new Path(getLocation().getString());
}
return workspacePath;
}
public List<NdWorkspaceLocation> getWorkspaceMappings() {
return WORKSPACE_MAPPINGS.asList(getNd(), this.address);
}
public IString getLocation() {
return FILENAME.get(getNd(), this.address);
}
public void setLocation(String filename) {
FILENAME.put(getNd(), this.address, filename);
}
public FileFingerprint getFingerprint() {
return new FileFingerprint(
getTimeLastScanned(),
getSizeLastScanned(),
getHashcodeLastScanned());
}
private long getHashcodeLastScanned() {
return HASHCODE_LAST_SCANNED.get(getNd(), this.address);
}
public boolean isDoneIndexing() {
return getTimeLastScanned() != 0;
}
public long getTimeLastScanned() {
return TIME_LAST_SCANNED.get(getNd(), this.address);
}
public long getSizeLastScanned() {
return SIZE_LAST_SCANNED.get(getNd(), this.address);
}
public long getTimeLastUsed() {
return TIME_LAST_USED.get(getNd(), this.address);
}
public void setTimeLastUsed(long timeLastUsed) {
TIME_LAST_USED.put(getNd(), this.address, timeLastUsed);
}
public void setFingerprint(FileFingerprint newFingerprint) {
TIME_LAST_SCANNED.put(getNd(), this.address, newFingerprint.getTime());
HASHCODE_LAST_SCANNED.put(getNd(), this.address, newFingerprint.getHash());
SIZE_LAST_SCANNED.put(getNd(), this.address, newFingerprint.getSize());
}
public void setPackageFragmentRoot(char[] javaRoot) {
JAVA_ROOT.put(getNd(), this.address, javaRoot);
}
public IString getPackageFragmentRoot() {
IString javaRoot = JAVA_ROOT.get(getNd(), this.address);
if (javaRoot.length() == 0) {
return getLocation();
}
return javaRoot;
}
public void markAsInvalid() {
TIME_LAST_SCANNED.put(getNd(), this.address, 0);
}
public int getTypeCount() {
return TYPES.size(getNd(), this.address);
}
public List<NdType> getTypes() {
return TYPES.asList(getNd(), this.address);
}
public NdType getType(int index) {
return TYPES.get(getNd(), this.address, index);
}
@Override
public String toString() {
try {
return FILENAME.get(getNd(), this.address).toString();
} catch (RuntimeException e) {
return super.toString();
}
}
public void allocateZipEntries(int expectedNumberOfZipEntries) {
ZIP_ENTRIES.allocate(this.nd, this.address, expectedNumberOfZipEntries);
}
public NdZipEntry addZipEntry(String fileName) {
NdZipEntry result = ZIP_ENTRIES.append(getNd(), getAddress());
result.setFilename(fileName);
return result;
}
}