blob: 61eb9e2ef24798463a56ef05a50b4ad061803803 [file] [log] [blame]
package org.jetbrains.jps.android;
import com.intellij.openapi.util.Pair;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import gnu.trove.TObjectLongHashMap;
import org.jetbrains.android.util.ResourceEntry;
import org.jetbrains.android.util.ResourceFileData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.incremental.storage.ValidityState;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.*;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidAptValidityState implements ValidityState {
private static final int SIGNATURE = 0xDEADBEEF;
private static final byte VERSION = 1;
private final Map<String, ResourceFileData> myResources;
private final TObjectLongHashMap<String> myValueResourceFilesTimestamps;
private final List<ResourceEntry> myManifestElements;
private final String myPackageName;
private final Set<Pair<String, String>> myLibRTxtFilesAndPackages;
private final String myProguardOutputCfgFile;
private final String myRTxtOutputDir;
private final boolean myLibrary;
public AndroidAptValidityState(@NotNull Map<String, ResourceFileData> resources,
@NotNull TObjectLongHashMap<String> valueResourceFilesTimestamps,
@NotNull List<ResourceEntry> manifestElements,
@NotNull Collection<Pair<String, String>> libRTxtFilesAndPackages,
@NotNull String packageName,
@Nullable String proguardOutputCfgFile,
@Nullable String rTxtOutputDir,
boolean library) {
myResources = resources;
myValueResourceFilesTimestamps = valueResourceFilesTimestamps;
myManifestElements = manifestElements;
myLibRTxtFilesAndPackages = new HashSet<Pair<String, String>>(libRTxtFilesAndPackages);
myPackageName = packageName;
myProguardOutputCfgFile = proguardOutputCfgFile != null ? proguardOutputCfgFile : "";
myRTxtOutputDir = rTxtOutputDir != null ? rTxtOutputDir : "";
myLibrary = library;
}
public AndroidAptValidityState(@NotNull DataInput in) throws IOException {
final int signature = in.readInt();
if (signature != SIGNATURE) {
throw new IOException("incorrect signature");
}
final byte version = in.readByte();
if (version != VERSION) {
throw new IOException("old version");
}
myPackageName = in.readUTF();
final int filesCount = in.readInt();
myResources = new HashMap<String, ResourceFileData>(filesCount);
for (int i = 0; i < filesCount; i++) {
final String filePath = in.readUTF();
final int entriesCount = in.readInt();
final List<ResourceEntry> entries = new ArrayList<ResourceEntry>(entriesCount);
for (int j = 0; j < entriesCount; j++) {
final String resType = in.readUTF();
final String resName = in.readUTF();
final String resContext = in.readUTF();
entries.add(new ResourceEntry(resType, resName, resContext));
}
final long timestamp = in.readLong();
myResources.put(filePath, new ResourceFileData(entries, timestamp));
}
final int manifestElementCount = in.readInt();
myManifestElements = new ArrayList<ResourceEntry>(manifestElementCount);
for (int i = 0; i < manifestElementCount; i++) {
final String elementType = in.readUTF();
final String elementName = in.readUTF();
final String elementContext = in.readUTF();
myManifestElements.add(new ResourceEntry(elementType, elementName, elementContext));
}
final int libPackageCount = in.readInt();
myLibRTxtFilesAndPackages = new HashSet<Pair<String, String>>(libPackageCount);
for (int i = 0; i < libPackageCount; i++) {
final String libRTxtFilePath = in.readUTF();
final String libPackage = in.readUTF();
myLibRTxtFilesAndPackages.add(Pair.create(libRTxtFilePath, libPackage));
}
myProguardOutputCfgFile = in.readUTF();
myRTxtOutputDir = in.readUTF();
myLibrary = in.readBoolean();
final int valueResourceFilesCount = in.readInt();
myValueResourceFilesTimestamps = new TObjectLongHashMap<String>(valueResourceFilesCount);
for (int i = 0; i < valueResourceFilesCount; i++) {
final String filePath = in.readUTF();
final long timestamp = in.readLong();
myValueResourceFilesTimestamps.put(filePath, timestamp);
}
}
@Override
public boolean equalsTo(ValidityState otherState) {
if (!(otherState instanceof AndroidAptValidityState)) {
return false;
}
// we do not compare myValueResourceFilesTimestamps maps here, because we don't run apt if some value resource xml files were changed,
// but whole set of value resources was not. These maps are checked by AndroidSourceGeneratingBuilder for optimization only
final AndroidAptValidityState otherAndroidState = (AndroidAptValidityState)otherState;
return otherAndroidState.myPackageName.equals(myPackageName) &&
otherAndroidState.myResources.equals(myResources) &&
otherAndroidState.myManifestElements.equals(myManifestElements) &&
otherAndroidState.myLibRTxtFilesAndPackages.equals(myLibRTxtFilesAndPackages) &&
otherAndroidState.myProguardOutputCfgFile.equals(myProguardOutputCfgFile) &&
otherAndroidState.myRTxtOutputDir.equals(myRTxtOutputDir) &&
otherAndroidState.myLibrary == myLibrary;
}
@Override
public void save(DataOutput out) throws IOException {
out.writeInt(SIGNATURE);
out.writeByte(VERSION);
out.writeUTF(myPackageName);
out.writeInt(myResources.size());
for (Map.Entry<String, ResourceFileData> entry : myResources.entrySet()) {
out.writeUTF(entry.getKey());
final ResourceFileData fileData = entry.getValue();
final List<ResourceEntry> resources = fileData.getValueResources();
out.writeInt(resources.size());
for (ResourceEntry resource : resources) {
out.writeUTF(resource.getType());
out.writeUTF(resource.getName());
out.writeUTF(resource.getContext());
}
out.writeLong(fileData.getTimestamp());
}
out.writeInt(myManifestElements.size());
for (ResourceEntry manifestElement : myManifestElements) {
out.writeUTF(manifestElement.getType());
out.writeUTF(manifestElement.getName());
out.writeUTF(manifestElement.getContext());
}
out.writeInt(myLibRTxtFilesAndPackages.size());
for (Pair<String, String> pair : myLibRTxtFilesAndPackages) {
out.writeUTF(pair.getFirst());
out.writeUTF(pair.getSecond());
}
out.writeUTF(myProguardOutputCfgFile);
out.writeUTF(myRTxtOutputDir);
out.writeBoolean(myLibrary);
out.writeInt(myValueResourceFilesTimestamps.size());
for (Object key : myValueResourceFilesTimestamps.keys()) {
final String strKey = (String)key;
out.writeUTF(strKey);
out.writeLong(myValueResourceFilesTimestamps.get(strKey));
}
}
public Map<String, ResourceFileData> getResources() {
return myResources;
}
public TObjectLongHashMap<String> getValueResourceFilesTimestamps() {
return myValueResourceFilesTimestamps;
}
}