| 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; |
| } |
| } |