package japicmp.util;
import com.google.common.base.Optional;
import japicmp.cmp.JarArchiveComparatorOptions;
import japicmp.config.Options;
import japicmp.model.*;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.CtField;
import java.lang.reflect.Modifier;
public class ModifierHelper {
public static final int ACC_BRIDGE = 0x00000040;
public static final int ACC_SYNTHETIC = 0x00001000;
private ModifierHelper() {
}
public static boolean matchesModifierLevel(AccessModifier modifierLevelOfElement, AccessModifier modifierLevel) {
return (modifierLevelOfElement.getLevel() >= modifierLevel.getLevel());
}
public static boolean matchesModifierLevel(int modifierOfElement, AccessModifier modifierLevel) {
AccessModifier modifierLevelOfElement = translateToModifierLevel(modifierOfElement);
return matchesModifierLevel(modifierLevelOfElement, modifierLevel);
}
public static AccessModifier translateToModifierLevel(int modifier) {
if (Modifier.isPublic(modifier)) {
return AccessModifier.PUBLIC;
} else if (Modifier.isProtected(modifier)) {
return AccessModifier.PROTECTED;
} else if (Modifier.isPrivate(modifier)) {
return AccessModifier.PRIVATE;
} else {
return AccessModifier.PACKAGE_PROTECTED;
}
}
public static boolean isNotPrivate(JApiHasAccessModifier jApiHasAccessModifier) {
JApiModifier<AccessModifier> accessModifier = jApiHasAccessModifier.getAccessModifier();
if (accessModifier.getOldModifier().isPresent() && accessModifier.getNewModifier().isPresent()) {
if (accessModifier.getNewModifier().get().getLevel() > AccessModifier.PRIVATE.getLevel() || accessModifier.getOldModifier().get().getLevel() > AccessModifier.PRIVATE.getLevel()) {
return true;
}
} else if (!accessModifier.getOldModifier().isPresent() && accessModifier.getNewModifier().isPresent()) {
if (accessModifier.getNewModifier().get().getLevel() > AccessModifier.PRIVATE.getLevel()) {
return true;
}
} else if (accessModifier.getOldModifier().isPresent() && !accessModifier.getNewModifier().isPresent()) {
if (accessModifier.getOldModifier().get().getLevel() > AccessModifier.PRIVATE.getLevel()) {
return true;
}
}
return false;
}
public static boolean hasModifierLevelDecreased(JApiHasAccessModifier hasAccessModifier) {
JApiModifier<AccessModifier> accessModifier = hasAccessModifier.getAccessModifier();
if (accessModifier.getOldModifier().isPresent() && accessModifier.getNewModifier().isPresent()) {
AccessModifier oldModifier = accessModifier.getOldModifier().get();
AccessModifier newModifier = accessModifier.getNewModifier().get();
if (newModifier.getLevel() < oldModifier.getLevel()) {
return true;
}
}
return false;
}
public static boolean matchesModifierLevel(JApiHasAccessModifier hasAccessModifier, AccessModifier accessModifierParam) {
JApiModifier<AccessModifier> accessModifier = hasAccessModifier.getAccessModifier();
if (accessModifier.getOldModifier().isPresent()) {
AccessModifier oldModifier = accessModifier.getOldModifier().get();
if (matchesModifierLevel(oldModifier, accessModifierParam)) {
return true;
}
}
if (accessModifier.getNewModifier().isPresent()) {
AccessModifier newModifier = accessModifier.getNewModifier().get();
if (matchesModifierLevel(newModifier, accessModifierParam)) {
return true;
}
}
return false;
}
public interface ExtractModifierFromClassCallback<T extends JApiModifierBase> {
T getModifierForOld(CtClass oldClass);
T getModifierForNew(CtClass newClass);
}
public static <T extends JApiModifierBase> JApiModifier<T> extractModifierFromClass(Optional<CtClass> oldClassOptional, Optional<CtClass> newClassOptional, ExtractModifierFromClassCallback<T> callback) {
if (oldClassOptional.isPresent() && newClassOptional.isPresent()) {
CtClass oldClass = oldClassOptional.get();
CtClass newClass = newClassOptional.get();
T oldClassModifier = callback.getModifierForOld(oldClass);
T newClassModifier = callback.getModifierForNew(newClass);
if (oldClassModifier != newClassModifier) {
return new JApiModifier<T>(Optional.of(oldClassModifier), Optional.of(newClassModifier), JApiChangeStatus.MODIFIED);
} else {
return new JApiModifier<T>(Optional.of(oldClassModifier), Optional.of(newClassModifier), JApiChangeStatus.UNCHANGED);
}
} else {
if (oldClassOptional.isPresent()) {
CtClass oldClass = oldClassOptional.get();
T oldClassModifier = callback.getModifierForOld(oldClass);
return new JApiModifier<T>(Optional.of(oldClassModifier), Optional.<T>absent(), JApiChangeStatus.REMOVED);
}
if (newClassOptional.isPresent()) {
CtClass newClass = newClassOptional.get();
T newClassModifier = callback.getModifierForNew(newClass);
return new JApiModifier<T>(Optional.<T>absent(), Optional.of(newClassModifier), JApiChangeStatus.NEW);
}
}
return new JApiModifier<T>(Optional.<T>absent(), Optional.<T>absent(), JApiChangeStatus.UNCHANGED);
}
public interface ExtractModifierFromBehaviorCallback<T extends JApiModifierBase> {
T getModifierForOld(CtBehavior oldClass);
T getModifierForNew(CtBehavior newClass);
}
public static <T extends JApiModifierBase> JApiModifier<T> extractModifierFromBehavior(Optional<? extends CtBehavior> oldClassOptional, Optional<? extends CtBehavior> newClassOptional, ExtractModifierFromBehaviorCallback<T> callback) {
if (oldClassOptional.isPresent() && newClassOptional.isPresent()) {
CtBehavior oldClass = oldClassOptional.get();
CtBehavior newClass = newClassOptional.get();
T oldClassModifier = callback.getModifierForOld(oldClass);
T newClassModifier = callback.getModifierForNew(newClass);
if (oldClassModifier != newClassModifier) {
return new JApiModifier<T>(Optional.of(oldClassModifier), Optional.of(newClassModifier), JApiChangeStatus.MODIFIED);
} else {
return new JApiModifier<T>(Optional.of(oldClassModifier), Optional.of(newClassModifier), JApiChangeStatus.UNCHANGED);
}
} else {
if (oldClassOptional.isPresent()) {
CtBehavior oldClass = oldClassOptional.get();
T oldClassModifier = callback.getModifierForOld(oldClass);
return new JApiModifier<T>(Optional.of(oldClassModifier), Optional.<T>absent(), JApiChangeStatus.REMOVED);
}
if (newClassOptional.isPresent()) {
CtBehavior newClass = newClassOptional.get();
T newClassModifier = callback.getModifierForNew(newClass);
return new JApiModifier<T>(Optional.<T>absent(), Optional.of(newClassModifier), JApiChangeStatus.NEW);
}
}
return new JApiModifier<T>(Optional.<T>absent(), Optional.<T>absent(), JApiChangeStatus.UNCHANGED);
}
public interface ExtractModifierFromFieldCallback<T extends JApiModifierBase> {
T getModifierForOld(CtField oldField);
T getModifierForNew(CtField newField);
}
public static <T extends JApiModifierBase> JApiModifier<T> extractModifierFromField(Optional<CtField> oldFieldOptional, Optional<CtField> newFieldOptional, ExtractModifierFromFieldCallback<T> callback) {
if (oldFieldOptional.isPresent() && newFieldOptional.isPresent()) {
CtField oldField = oldFieldOptional.get();
CtField newField = newFieldOptional.get();
T oldFieldModifier = callback.getModifierForOld(oldField);
T newFieldModifier = callback.getModifierForNew(newField);
if (oldFieldModifier != newFieldModifier) {
return new JApiModifier<T>(Optional.of(oldFieldModifier), Optional.of(newFieldModifier), JApiChangeStatus.MODIFIED);
} else {
return new JApiModifier<T>(Optional.of(oldFieldModifier), Optional.of(newFieldModifier), JApiChangeStatus.UNCHANGED);
}
} else {
if (oldFieldOptional.isPresent()) {
CtField oldField = oldFieldOptional.get();
T oldFieldModifier = callback.getModifierForOld(oldField);
return new JApiModifier<T>(Optional.of(oldFieldModifier), Optional.<T>absent(), JApiChangeStatus.REMOVED);
}
if (newFieldOptional.isPresent()) {
CtField newField = newFieldOptional.get();
T newFieldModifier = callback.getModifierForNew(newField);
return new JApiModifier<T>(Optional.<T>absent(), Optional.of(newFieldModifier), JApiChangeStatus.NEW);
}
}
return new JApiModifier<T>(Optional.<T>absent(), Optional.<T>absent(), JApiChangeStatus.UNCHANGED);
}
public static boolean isBridge(int modifier) {
return (modifier & ACC_BRIDGE) != 0;
}
public static boolean isSynthetic(int modifier) {
return (modifier & ACC_SYNTHETIC) != 0;
}
public static boolean includeSynthetic(JApiCanBeSynthetic jApiCanBeSynthetic, JarArchiveComparatorOptions options) {
return options.isIncludeSynthetic() || !isSynthetic(jApiCanBeSynthetic);
}
public static boolean includeSynthetic(JApiCanBeSynthetic jApiCanBeSynthetic, Options options) {
return !isSynthetic(jApiCanBeSynthetic) || options.isIncludeSynthetic();
}
public static boolean isSynthetic(JApiCanBeSynthetic jApiClass) {
boolean isSynthetic = false;
JApiModifier<SyntheticModifier> syntheticModifier = jApiClass.getSyntheticModifier();
JApiAttribute<SyntheticAttribute> syntheticAttribute = jApiClass.getSyntheticAttribute();
boolean hasSyntheticModifier = hasSyntheticModifier(syntheticModifier);
boolean hasSyntheticAttribute = hasSyntheticAttribute(syntheticAttribute);
if (hasSyntheticModifier || hasSyntheticAttribute) {
isSynthetic = true;
}
return isSynthetic;
}
private static boolean hasSyntheticAttribute(JApiAttribute<SyntheticAttribute> syntheticAttribute) {
boolean hasSyntheticAttribute = false;
if (syntheticAttribute.getOldAttribute().isPresent() && syntheticAttribute.getNewAttribute().isPresent()) {
SyntheticAttribute oldAttribute = syntheticAttribute.getOldAttribute().get();
SyntheticAttribute newAttribute = syntheticAttribute.getNewAttribute().get();
if (oldAttribute == SyntheticAttribute.SYNTHETIC && newAttribute == SyntheticAttribute.SYNTHETIC) {
hasSyntheticAttribute = true;
}
} else if (syntheticAttribute.getOldAttribute().isPresent()) {
SyntheticAttribute oldAttribute = syntheticAttribute.getOldAttribute().get();
if (oldAttribute == SyntheticAttribute.SYNTHETIC) {
hasSyntheticAttribute = true;
}
} else if (syntheticAttribute.getNewAttribute().isPresent()) {
SyntheticAttribute newAttribute = syntheticAttribute.getNewAttribute().get();
if (newAttribute == SyntheticAttribute.SYNTHETIC) {
hasSyntheticAttribute = true;
}
}
return hasSyntheticAttribute;
}
private static boolean hasSyntheticModifier(JApiModifier<SyntheticModifier> syntheticModifier) {
boolean hasSyntheticModifer = false;
if (syntheticModifier.getOldModifier().isPresent() && syntheticModifier.getNewModifier().isPresent()) {
SyntheticModifier oldModifier = syntheticModifier.getOldModifier().get();
SyntheticModifier newModifier = syntheticModifier.getNewModifier().get();
if (oldModifier == SyntheticModifier.SYNTHETIC && newModifier == SyntheticModifier.SYNTHETIC) {
hasSyntheticModifer = true;
}
} else if (syntheticModifier.getOldModifier().isPresent()) {
SyntheticModifier oldModifier = syntheticModifier.getOldModifier().get();
if (oldModifier == SyntheticModifier.SYNTHETIC) {
hasSyntheticModifer = true;
}
} else if (syntheticModifier.getNewModifier().isPresent()) {
SyntheticModifier newModifier = syntheticModifier.getNewModifier().get();
if (newModifier == SyntheticModifier.SYNTHETIC) {
hasSyntheticModifer = true;
}
}
return hasSyntheticModifer;
}
}