/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.core.builder; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.env.AccessRule; import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; import org.eclipse.jdt.internal.core.ClasspathAccessRule; import org.eclipse.jdt.internal.core.JavaModelManager; public class State { // NOTE: this state cannot contain types that are not defined in this project String javaProjectName; ClasspathMultiDirectory[] sourceLocations; ClasspathLocation[] binaryLocations; // keyed by the project relative path of the type (ie. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection SimpleLookupTable references; // keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java" public SimpleLookupTable typeLocators; int buildNumber; long lastStructuralBuildTime; SimpleLookupTable structuralBuildTimes; private String[] knownPackageNames; // of the form "p1/p2" private long previousStructuralBuildTime; private StringSet structurallyChangedTypes; public static int MaxStructurallyChangedTypes= 100; // keep track of ? structurally changed types, otherwise consider all to be changed public static final byte VERSION= 0x0018; // fix for 291472 static final byte SOURCE_FOLDER= 1; static final byte BINARY_FOLDER= 2; static final byte EXTERNAL_JAR= 3; static final byte INTERNAL_JAR= 4; State() { // constructor with no argument } protected State(JavaBuilder javaBuilder) { this.knownPackageNames= null; this.previousStructuralBuildTime= -1; this.structurallyChangedTypes= null; this.javaProjectName= javaBuilder.currentProject.getName(); this.sourceLocations= javaBuilder.nameEnvironment.sourceLocations; this.binaryLocations= javaBuilder.nameEnvironment.binaryLocations; this.references= new SimpleLookupTable(7); this.typeLocators= new SimpleLookupTable(7); this.buildNumber= 0; // indicates a full build this.lastStructuralBuildTime= computeStructuralBuildTime(javaBuilder.lastState == null ? 0 : javaBuilder.lastState.lastStructuralBuildTime); this.structuralBuildTimes= new SimpleLookupTable(3); } long computeStructuralBuildTime(long previousTime) { long newTime= System.currentTimeMillis(); if (newTime <= previousTime) newTime= previousTime + 1; return newTime; } void copyFrom(State lastState) { this.knownPackageNames= null; this.previousStructuralBuildTime= lastState.previousStructuralBuildTime; this.structurallyChangedTypes= lastState.structurallyChangedTypes; this.buildNumber= lastState.buildNumber + 1; this.lastStructuralBuildTime= lastState.lastStructuralBuildTime; this.structuralBuildTimes= lastState.structuralBuildTimes; try { this.references= (SimpleLookupTable)lastState.references.clone(); this.typeLocators= (SimpleLookupTable)lastState.typeLocators.clone(); } catch (CloneNotSupportedException e) { this.references= new SimpleLookupTable(lastState.references.elementSize); Object[] keyTable= lastState.references.keyTable; Object[] valueTable= lastState.references.valueTable; for (int i= 0, l= keyTable.length; i < l; i++) if (keyTable[i] != null) this.references.put(keyTable[i], valueTable[i]); this.typeLocators= new SimpleLookupTable(lastState.typeLocators.elementSize); keyTable= lastState.typeLocators.keyTable; valueTable= lastState.typeLocators.valueTable; for (int i= 0, l= keyTable.length; i < l; i++) if (keyTable[i] != null) this.typeLocators.put(keyTable[i], valueTable[i]); } } public char[][] getDefinedTypeNamesFor(String typeLocator) { Object c= this.references.get(typeLocator); if (c instanceof AdditionalTypeCollection) return ((AdditionalTypeCollection)c).definedTypeNames; return null; // means only one type is defined with the same name as the file... saves space } public SimpleLookupTable getReferences() { return this.references; } StringSet getStructurallyChangedTypes(State prereqState) { if (prereqState != null && prereqState.previousStructuralBuildTime > 0) { Object o= this.structuralBuildTimes.get(prereqState.javaProjectName); long previous= o == null ? 0 : ((Long)o).longValue(); if (previous == prereqState.previousStructuralBuildTime) return prereqState.structurallyChangedTypes; } return null; } public boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) { String existing= (String)this.typeLocators.get(qualifiedTypeName); return existing != null && !existing.equals(typeLocator); } public boolean isKnownPackage(String qualifiedPackageName) { if (this.knownPackageNames == null) { ArrayList names= new ArrayList(this.typeLocators.elementSize); Object[] keyTable= this.typeLocators.keyTable; for (int i= 0, l= keyTable.length; i < l; i++) { if (keyTable[i] != null) { String packageName= (String)keyTable[i]; // is a type name of the form p1/p2/A int last= packageName.lastIndexOf('/'); packageName= last == -1 ? null : packageName.substring(0, last); while (packageName != null && !names.contains(packageName)) { names.add(packageName); last= packageName.lastIndexOf('/'); packageName= last == -1 ? null : packageName.substring(0, last); } } } this.knownPackageNames= new String[names.size()]; names.toArray(this.knownPackageNames); } for (int i= 0, l= this.knownPackageNames.length; i < l; i++) if (this.knownPackageNames[i].equals(qualifiedPackageName)) return true; return false; } public boolean isKnownType(String qualifiedTypeName) { return this.typeLocators.containsKey(qualifiedTypeName); } boolean isSourceFolderEmpty(IContainer sourceFolder) { String sourceFolderName= sourceFolder.getProjectRelativePath().addTrailingSeparator().toString(); Object[] table= this.typeLocators.valueTable; for (int i= 0, l= table.length; i < l; i++) if (table[i] != null && ((String)table[i]).startsWith(sourceFolderName)) return false; return true; } void record(String typeLocator, char[][][] qualifiedRefs, char[][] simpleRefs, char[][] rootRefs, char[] mainTypeName, ArrayList typeNames) { if (typeNames.size() == 1 && CharOperation.equals(mainTypeName, (char[])typeNames.get(0))) { this.references.put(typeLocator, new ReferenceCollection(qualifiedRefs, simpleRefs, rootRefs)); } else { char[][] definedTypeNames= new char[typeNames.size()][]; // can be empty when no types are defined typeNames.toArray(definedTypeNames); this.references.put(typeLocator, new AdditionalTypeCollection(definedTypeNames, qualifiedRefs, simpleRefs, rootRefs)); } } void recordLocatorForType(String qualifiedTypeName, String typeLocator) { this.knownPackageNames= null; // in the common case, the qualifiedTypeName is a substring of the typeLocator so share the char[] by using String.substring() int start= typeLocator.indexOf(qualifiedTypeName, 0); if (start > 0) qualifiedTypeName= typeLocator.substring(start, start + qualifiedTypeName.length()); this.typeLocators.put(qualifiedTypeName, typeLocator); } void recordStructuralDependency(IProject prereqProject, State prereqState) { if (prereqState != null) if (prereqState.lastStructuralBuildTime > 0) // can skip if 0 (full build) since its assumed to be 0 if unknown this.structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime)); } void removeLocator(String typeLocatorToRemove) { this.knownPackageNames= null; this.references.removeKey(typeLocatorToRemove); this.typeLocators.removeValue(typeLocatorToRemove); } void removePackage(IResourceDelta sourceDelta) { IResource resource= sourceDelta.getResource(); switch (resource.getType()) { case IResource.FOLDER: IResourceDelta[] children= sourceDelta.getAffectedChildren(); for (int i= 0, l= children.length; i < l; i++) removePackage(children[i]); return; case IResource.FILE: IPath typeLocatorPath= resource.getProjectRelativePath(); if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(typeLocatorPath.lastSegment())) removeLocator(typeLocatorPath.toString()); } } void removeQualifiedTypeName(String qualifiedTypeNameToRemove) { this.knownPackageNames= null; this.typeLocators.removeKey(qualifiedTypeNameToRemove); } static State read(IProject project, DataInputStream in) throws IOException { if (JavaBuilder.DEBUG) System.out.println("About to read state " + project.getName()); //$NON-NLS-1$ if (VERSION != in.readByte()) { if (JavaBuilder.DEBUG) System.out.println("Found non-compatible state version... answered null for " + project.getName()); //$NON-NLS-1$ return null; } State newState= new State(); newState.javaProjectName= in.readUTF(); if (!project.getName().equals(newState.javaProjectName)) { if (JavaBuilder.DEBUG) System.out.println("Project's name does not match... answered null"); //$NON-NLS-1$ return null; } newState.buildNumber= in.readInt(); newState.lastStructuralBuildTime= in.readLong(); int length= in.readInt(); newState.sourceLocations= new ClasspathMultiDirectory[length]; for (int i= 0; i < length; i++) { IContainer sourceFolder= project, outputFolder= project; String folderName; if ((folderName= in.readUTF()).length() > 0) sourceFolder= project.getFolder(folderName); if ((folderName= in.readUTF()).length() > 0) outputFolder= project.getFolder(folderName); ClasspathMultiDirectory md= (ClasspathMultiDirectory)ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in), readNames(in)); if (in.readBoolean()) md.hasIndependentOutputFolder= true; newState.sourceLocations[i]= md; } length= in.readInt(); newState.binaryLocations= new ClasspathLocation[length]; IWorkspaceRoot root= project.getWorkspace().getRoot(); for (int i= 0; i < length; i++) { switch (in.readByte()) { case SOURCE_FOLDER: newState.binaryLocations[i]= newState.sourceLocations[in.readInt()]; break; case BINARY_FOLDER: IPath path= new Path(in.readUTF()); IContainer outputFolder= path.segmentCount() == 1 ? (IContainer)root.getProject(path.toString()) : (IContainer)root.getFolder(path); newState.binaryLocations[i]= ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean(), readRestriction(in)); break; case EXTERNAL_JAR: newState.binaryLocations[i]= ClasspathLocation.forLibrary(in.readUTF(), in.readLong(), readRestriction(in)); break; case INTERNAL_JAR: newState.binaryLocations[i]= ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())), readRestriction(in)); } } newState.structuralBuildTimes= new SimpleLookupTable(length= in.readInt()); for (int i= 0; i < length; i++) newState.structuralBuildTimes.put(in.readUTF(), new Long(in.readLong())); String[] internedTypeLocators= new String[length= in.readInt()]; for (int i= 0; i < length; i++) internedTypeLocators[i]= in.readUTF(); newState.typeLocators= new SimpleLookupTable(length= in.readInt()); for (int i= 0; i < length; i++) newState.recordLocatorForType(in.readUTF(), internedTypeLocators[in.readInt()]); char[][] internedRootNames= ReferenceCollection.internSimpleNames(readNames(in), false); char[][] internedSimpleNames= ReferenceCollection.internSimpleNames(readNames(in), false); char[][][] internedQualifiedNames= new char[length= in.readInt()][][]; for (int i= 0; i < length; i++) { int qLength= in.readInt(); char[][] qName= new char[qLength][]; for (int j= 0; j < qLength; j++) qName[j]= internedSimpleNames[in.readInt()]; internedQualifiedNames[i]= qName; } internedQualifiedNames= ReferenceCollection.internQualifiedNames(internedQualifiedNames); newState.references= new SimpleLookupTable(length= in.readInt()); for (int i= 0; i < length; i++) { String typeLocator= internedTypeLocators[in.readInt()]; ReferenceCollection collection= null; switch (in.readByte()) { case 1: char[][] additionalTypeNames= readNames(in); char[][][] qualifiedNames= new char[in.readInt()][][]; for (int j= 0, m= qualifiedNames.length; j < m; j++) qualifiedNames[j]= internedQualifiedNames[in.readInt()]; char[][] simpleNames= new char[in.readInt()][]; for (int j= 0, m= simpleNames.length; j < m; j++) simpleNames[j]= internedSimpleNames[in.readInt()]; char[][] rootNames= new char[in.readInt()][]; for (int j= 0, m= rootNames.length; j < m; j++) rootNames[j]= internedRootNames[in.readInt()]; collection= new AdditionalTypeCollection(additionalTypeNames, qualifiedNames, simpleNames, rootNames); break; case 2: char[][][] qNames= new char[in.readInt()][][]; for (int j= 0, m= qNames.length; j < m; j++) qNames[j]= internedQualifiedNames[in.readInt()]; char[][] sNames= new char[in.readInt()][]; for (int j= 0, m= sNames.length; j < m; j++) sNames[j]= internedSimpleNames[in.readInt()]; char[][] rNames= new char[in.readInt()][]; for (int j= 0, m= rNames.length; j < m; j++) rNames[j]= internedRootNames[in.readInt()]; collection= new ReferenceCollection(qNames, sNames, rNames); } newState.references.put(typeLocator, collection); } if (JavaBuilder.DEBUG) System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$ return newState; } private static char[] readName(DataInputStream in) throws IOException { int nLength= in.readInt(); char[] name= new char[nLength]; for (int j= 0; j < nLength; j++) name[j]= in.readChar(); return name; } private static char[][] readNames(DataInputStream in) throws IOException { int length= in.readInt(); char[][] names= new char[length][]; for (int i= 0; i < length; i++) names[i]= readName(in); return names; } private static AccessRuleSet readRestriction(DataInputStream in) throws IOException { int length= in.readInt(); if (length == 0) return null; // no restriction specified AccessRule[] accessRules= new AccessRule[length]; for (int i= 0; i < length; i++) { char[] pattern= readName(in); int problemId= in.readInt(); accessRules[i]= new ClasspathAccessRule(pattern, problemId); } JavaModelManager manager= JavaModelManager.getJavaModelManager(); return new AccessRuleSet(accessRules, in.readByte(), manager.intern(in.readUTF())); } void tagAsNoopBuild() { this.buildNumber= -1; // tag the project since it has no source folders and can be skipped } boolean wasNoopBuild() { return this.buildNumber == -1; } void tagAsStructurallyChanged() { this.previousStructuralBuildTime= this.lastStructuralBuildTime; this.structurallyChangedTypes= new StringSet(7); this.lastStructuralBuildTime= computeStructuralBuildTime(this.previousStructuralBuildTime); } boolean wasStructurallyChanged(IProject prereqProject, State prereqState) { if (prereqState != null) { Object o= this.structuralBuildTimes.get(prereqProject.getName()); long previous= o == null ? 0 : ((Long)o).longValue(); if (previous == prereqState.lastStructuralBuildTime) return false; } return true; } void wasStructurallyChanged(String typeName) { if (this.structurallyChangedTypes != null) { if (this.structurallyChangedTypes.elementSize > MaxStructurallyChangedTypes) this.structurallyChangedTypes= null; // too many to keep track of else this.structurallyChangedTypes.add(typeName); } } void write(DataOutputStream out) throws IOException { int length; Object[] keyTable; Object[] valueTable; /* * byte VERSION * String project name * int build number * int last structural build number */ out.writeByte(VERSION); out.writeUTF(this.javaProjectName); out.writeInt(this.buildNumber); out.writeLong(this.lastStructuralBuildTime); /* * ClasspathMultiDirectory[] * int id * String path(s) */ out.writeInt(length= this.sourceLocations.length); for (int i= 0; i < length; i++) { ClasspathMultiDirectory md= this.sourceLocations[i]; out.writeUTF(md.sourceFolder.getProjectRelativePath().toString()); out.writeUTF(md.binaryFolder.getProjectRelativePath().toString()); writeNames(md.inclusionPatterns, out); writeNames(md.exclusionPatterns, out); out.writeBoolean(md.hasIndependentOutputFolder); } /* * ClasspathLocation[] * int id * String path(s) */ out.writeInt(length= this.binaryLocations.length); next: for (int i= 0; i < length; i++) { ClasspathLocation c= this.binaryLocations[i]; if (c instanceof ClasspathMultiDirectory) { out.writeByte(SOURCE_FOLDER); for (int j= 0, m= this.sourceLocations.length; j < m; j++) { if (this.sourceLocations[j] == c) { out.writeInt(j); continue next; } } } else if (c instanceof ClasspathDirectory) { out.writeByte(BINARY_FOLDER); ClasspathDirectory cd= (ClasspathDirectory)c; out.writeUTF(cd.binaryFolder.getFullPath().toString()); out.writeBoolean(cd.isOutputFolder); writeRestriction(cd.accessRuleSet, out); } else { ClasspathJar jar= (ClasspathJar)c; if (jar.resource == null) { out.writeByte(EXTERNAL_JAR); out.writeUTF(jar.zipFilename); out.writeLong(jar.lastModified()); } else { out.writeByte(INTERNAL_JAR); out.writeUTF(jar.resource.getFullPath().toString()); } writeRestriction(jar.accessRuleSet, out); } } /* * Structural build numbers table * String prereq project name * int last structural build number */ out.writeInt(length= this.structuralBuildTimes.elementSize); if (length > 0) { keyTable= this.structuralBuildTimes.keyTable; valueTable= this.structuralBuildTimes.valueTable; for (int i= 0, l= keyTable.length; i < l; i++) { if (keyTable[i] != null) { length--; out.writeUTF((String)keyTable[i]); out.writeLong(((Long)valueTable[i]).longValue()); } } if (JavaBuilder.DEBUG && length != 0) System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$ } /* * String[] Interned type locators */ out.writeInt(length= this.references.elementSize); SimpleLookupTable internedTypeLocators= new SimpleLookupTable(length); if (length > 0) { keyTable= this.references.keyTable; for (int i= 0, l= keyTable.length; i < l; i++) { if (keyTable[i] != null) { length--; String key= (String)keyTable[i]; out.writeUTF(key); internedTypeLocators.put(key, new Integer(internedTypeLocators.elementSize)); } } if (JavaBuilder.DEBUG && length != 0) System.out.println("references table is inconsistent"); //$NON-NLS-1$ } /* * Type locators table * String type name * int interned locator id */ out.writeInt(length= this.typeLocators.elementSize); if (length > 0) { keyTable= this.typeLocators.keyTable; valueTable= this.typeLocators.valueTable; for (int i= 0, l= keyTable.length; i < l; i++) { if (keyTable[i] != null) { length--; out.writeUTF((String)keyTable[i]); Integer index= (Integer)internedTypeLocators.get(valueTable[i]); out.writeInt(index.intValue()); } } if (JavaBuilder.DEBUG && length != 0) System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$ } /* * char[][] Interned root names * char[][][] Interned qualified names * char[][] Interned simple names */ SimpleLookupTable internedRootNames= new SimpleLookupTable(3); SimpleLookupTable internedQualifiedNames= new SimpleLookupTable(31); SimpleLookupTable internedSimpleNames= new SimpleLookupTable(31); valueTable= this.references.valueTable; for (int i= 0, l= valueTable.length; i < l; i++) { if (valueTable[i] != null) { ReferenceCollection collection= (ReferenceCollection)valueTable[i]; char[][] rNames= collection.rootReferences; for (int j= 0, m= rNames.length; j < m; j++) { char[] rName= rNames[j]; if (!internedRootNames.containsKey(rName)) // remember the names have been interned internedRootNames.put(rName, new Integer(internedRootNames.elementSize)); } char[][][] qNames= collection.qualifiedNameReferences; for (int j= 0, m= qNames.length; j < m; j++) { char[][] qName= qNames[j]; if (!internedQualifiedNames.containsKey(qName)) { // remember the names have been interned internedQualifiedNames.put(qName, new Integer(internedQualifiedNames.elementSize)); for (int k= 0, n= qName.length; k < n; k++) { char[] sName= qName[k]; if (!internedSimpleNames.containsKey(sName)) // remember the names have been interned internedSimpleNames.put(sName, new Integer(internedSimpleNames.elementSize)); } } } char[][] sNames= collection.simpleNameReferences; for (int j= 0, m= sNames.length; j < m; j++) { char[] sName= sNames[j]; if (!internedSimpleNames.containsKey(sName)) // remember the names have been interned internedSimpleNames.put(sName, new Integer(internedSimpleNames.elementSize)); } } } char[][] internedArray= new char[internedRootNames.elementSize][]; Object[] rootNames= internedRootNames.keyTable; Object[] positions= internedRootNames.valueTable; for (int i= positions.length; --i >= 0;) { if (positions[i] != null) { int index= ((Integer)positions[i]).intValue(); internedArray[index]= (char[])rootNames[i]; } } writeNames(internedArray, out); // now write the interned simple names internedArray= new char[internedSimpleNames.elementSize][]; Object[] simpleNames= internedSimpleNames.keyTable; positions= internedSimpleNames.valueTable; for (int i= positions.length; --i >= 0;) { if (positions[i] != null) { int index= ((Integer)positions[i]).intValue(); internedArray[index]= (char[])simpleNames[i]; } } writeNames(internedArray, out); // now write the interned qualified names as arrays of interned simple names char[][][] internedQArray= new char[internedQualifiedNames.elementSize][][]; Object[] qualifiedNames= internedQualifiedNames.keyTable; positions= internedQualifiedNames.valueTable; for (int i= positions.length; --i >= 0;) { if (positions[i] != null) { int index= ((Integer)positions[i]).intValue(); internedQArray[index]= (char[][])qualifiedNames[i]; } } out.writeInt(length= internedQArray.length); for (int i= 0; i < length; i++) { char[][] qName= internedQArray[i]; int qLength= qName.length; out.writeInt(qLength); for (int j= 0; j < qLength; j++) { Integer index= (Integer)internedSimpleNames.get(qName[j]); out.writeInt(index.intValue()); } } /* * References table * int interned locator id * ReferenceCollection */ out.writeInt(length= this.references.elementSize); if (length > 0) { keyTable= this.references.keyTable; for (int i= 0, l= keyTable.length; i < l; i++) { if (keyTable[i] != null) { length--; Integer index= (Integer)internedTypeLocators.get(keyTable[i]); out.writeInt(index.intValue()); ReferenceCollection collection= (ReferenceCollection)valueTable[i]; if (collection instanceof AdditionalTypeCollection) { out.writeByte(1); AdditionalTypeCollection atc= (AdditionalTypeCollection)collection; writeNames(atc.definedTypeNames, out); } else { out.writeByte(2); } char[][][] qNames= collection.qualifiedNameReferences; int qLength= qNames.length; out.writeInt(qLength); for (int j= 0; j < qLength; j++) { index= (Integer)internedQualifiedNames.get(qNames[j]); out.writeInt(index.intValue()); } char[][] sNames= collection.simpleNameReferences; int sLength= sNames.length; out.writeInt(sLength); for (int j= 0; j < sLength; j++) { index= (Integer)internedSimpleNames.get(sNames[j]); out.writeInt(index.intValue()); } char[][] rNames= collection.rootReferences; int rLength= rNames.length; out.writeInt(rLength); for (int j= 0; j < rLength; j++) { index= (Integer)internedRootNames.get(rNames[j]); out.writeInt(index.intValue()); } } } if (JavaBuilder.DEBUG && length != 0) System.out.println("references table is inconsistent"); //$NON-NLS-1$ } } private void writeName(char[] name, DataOutputStream out) throws IOException { int nLength= name.length; out.writeInt(nLength); for (int j= 0; j < nLength; j++) out.writeChar(name[j]); } private void writeNames(char[][] names, DataOutputStream out) throws IOException { int length= names == null ? 0 : names.length; out.writeInt(length); for (int i= 0; i < length; i++) writeName(names[i], out); } private void writeRestriction(AccessRuleSet accessRuleSet, DataOutputStream out) throws IOException { if (accessRuleSet == null) { out.writeInt(0); } else { AccessRule[] accessRules= accessRuleSet.getAccessRules(); int length= accessRules.length; out.writeInt(length); if (length != 0) { for (int i= 0; i < length; i++) { AccessRule accessRule= accessRules[i]; writeName(accessRule.pattern, out); out.writeInt(accessRule.problemId); } out.writeByte(accessRuleSet.classpathEntryType); out.writeUTF(accessRuleSet.classpathEntryName); } } } /** * Returns a string representation of the receiver. */ public String toString() { return "State for " + this.javaProjectName //$NON-NLS-1$ + " (#" + this.buildNumber //$NON-NLS-1$ + " @ " + new Date(this.lastStructuralBuildTime) //$NON-NLS-1$ + ")"; //$NON-NLS-1$ } /* Debug helper void dump() { System.out.println("State for " + javaProjectName + " (" + buildNumber + " @ " + new Date(lastStructuralBuildTime) + ")"); System.out.println("\tClass path source locations:"); for (int i = 0, l = sourceLocations.length; i < l; i++) System.out.println("\t\t" + sourceLocations[i]); System.out.println("\tClass path binary locations:"); for (int i = 0, l = binaryLocations.length; i < l; i++) System.out.println("\t\t" + binaryLocations[i]); System.out.print("\tStructural build numbers table:"); if (structuralBuildTimes.elementSize == 0) { System.out.print(" <empty>"); } else { Object[] keyTable = structuralBuildTimes.keyTable; Object[] valueTable = structuralBuildTimes.valueTable; for (int i = 0, l = keyTable.length; i < l; i++) if (keyTable[i] != null) System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString()); } System.out.print("\tType locators table:"); if (typeLocators.elementSize == 0) { System.out.print(" <empty>"); } else { Object[] keyTable = typeLocators.keyTable; Object[] valueTable = typeLocators.valueTable; for (int i = 0, l = keyTable.length; i < l; i++) if (keyTable[i] != null) System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString()); } System.out.print("\n\tReferences table:"); if (references.elementSize == 0) { System.out.print(" <empty>"); } else { Object[] keyTable = references.keyTable; Object[] valueTable = references.valueTable; for (int i = 0, l = keyTable.length; i < l; i++) { if (keyTable[i] != null) { System.out.print("\n\t\t" + keyTable[i].toString()); ReferenceCollection c = (ReferenceCollection) valueTable[i]; char[][][] qRefs = c.qualifiedNameReferences; System.out.print("\n\t\t\tqualified:"); if (qRefs.length == 0) System.out.print(" <empty>"); else for (int j = 0, m = qRefs.length; j < m; j++) System.out.print(" '" + CharOperation.toString(qRefs[j]) + "'"); char[][] sRefs = c.simpleNameReferences; System.out.print("\n\t\t\tsimple:"); if (sRefs.length == 0) System.out.print(" <empty>"); else for (int j = 0, m = sRefs.length; j < m; j++) System.out.print(" " + new String(sRefs[j])); if (c instanceof AdditionalTypeCollection) { char[][] names = ((AdditionalTypeCollection) c).definedTypeNames; System.out.print("\n\t\t\tadditional type names:"); for (int j = 0, m = names.length; j < m; j++) System.out.print(" " + new String(names[j])); } } } } System.out.print("\n\n"); } */ }