/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.api.internal.tasks.compile.incremental.jar;
import com.google.common.collect.Sets;
import com.google.common.hash.HashCode;
import org.gradle.api.internal.tasks.compile.incremental.deps.AffectedClasses;
import org.gradle.api.internal.tasks.compile.incremental.deps.ClassSetAnalysis;
import org.gradle.api.internal.tasks.compile.incremental.deps.DefaultDependentsSet;
import org.gradle.api.internal.tasks.compile.incremental.deps.DependencyToAll;
import org.gradle.api.internal.tasks.compile.incremental.deps.DependentsSet;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class JarSnapshot {
private final JarSnapshotData data;
public JarSnapshot(JarSnapshotData data) {
this.data = data;
}
public DependentsSet getAllClasses() {
final Set<String> result = new HashSet<String>();
for (Map.Entry<String, HashCode> cls : getHashes().entrySet()) {
String className = cls.getKey();
if (getAnalysis().isDependencyToAll(className)) {
return new DependencyToAll();
}
result.add(className);
}
return new DefaultDependentsSet(result);
}
public Set<Integer> getAllConstants(DependentsSet dependents) {
Set<Integer> result = Sets.newHashSet();
for (String cn : dependents.getDependentClasses()) {
result.addAll(data.data.getConstants(cn));
}
return result;
}
public Set<Integer> getRelevantConstants(JarSnapshot other, Set<String> affectedClasses) {
Set<Integer> result = Sets.newHashSet();
for (String affectedClass : affectedClasses) {
Set<Integer> previous = other.getData().data.getConstants(affectedClass);
Set<Integer> current = data.data.getConstants(affectedClass);
result.addAll(Sets.difference(previous, current));
}
return result;
}
public AffectedClasses getAffectedClassesSince(JarSnapshot other) {
DependentsSet affectedClasses = affectedSince(other);
Set<String> addedClasses = addedSince(other);
return new AffectedClasses(affectedClasses, addedClasses);
}
private DependentsSet affectedSince(JarSnapshot other) {
final Set<String> affected = new HashSet<String>();
for (Map.Entry<String, HashCode> otherClass : other.getHashes().entrySet()) {
String otherClassName = otherClass.getKey();
HashCode otherClassBytes = otherClass.getValue();
HashCode thisClsBytes = getHashes().get(otherClassName);
if (thisClsBytes == null || !thisClsBytes.equals(otherClassBytes)) {
//removed since or changed since
affected.add(otherClassName);
DependentsSet dependents = other.getAnalysis().getRelevantDependents(otherClassName, Collections.<Integer>emptySet());
if (dependents.isDependencyToAll()) {
return dependents;
}
affected.addAll(dependents.getDependentClasses());
}
}
return new DefaultDependentsSet(affected);
}
private Set<String> addedSince(JarSnapshot other) {
Set<String> addedClasses = new HashSet<String>(getClasses());
addedClasses.removeAll(other.getClasses());
return addedClasses;
}
public HashCode getHash() {
return data.hash;
}
public Map<String, HashCode> getHashes() {
return data.hashes;
}
public ClassSetAnalysis getAnalysis() {
return new ClassSetAnalysis(data.data);
}
public Set<String> getClasses() {
return data.hashes.keySet();
}
public JarSnapshotData getData() {
return data;
}
}