/*
* Copyright 2017 TNG Technology Consulting GmbH
*
* 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 com.tngtech.archunit.core.domain;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ComparisonChain;
import com.tngtech.archunit.PublicAPI;
import com.tngtech.archunit.core.domain.properties.HasDescription;
import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
/**
* Represents a dependency of one Java class on another Java class. Such a dependency can occur by either of the
* following:
* <ul>
* <li>a class accesses a field of another class</li>
* <li>a class calls a method of another class</li>
* <li>a class calls a constructor of another class</li>
* <li>a class inherits from another class (which is in fact a special case of constructor call)</li>
* </ul>
*/
public class Dependency implements HasDescription, Comparable<Dependency> {
static Dependency from(JavaAccess<?> access) {
return new Dependency(access.getOriginOwner(), access.getTargetOwner(), access.getLineNumber(), access.getDescription());
}
static Dependency from(JavaClass origin, JavaClass target) {
String description = String.format("%s accesses %s in %s",
origin.getName(), target.getName(), Formatters.formatLocation(origin, 0));
return new Dependency(origin, target, 0, description);
}
private final JavaClass originClass;
private final JavaClass targetClass;
private final int lineNumber;
private final String description;
private Dependency(JavaClass originClass, JavaClass targetClass, int lineNumber, String description) {
this.originClass = originClass;
this.targetClass = targetClass;
this.lineNumber = lineNumber;
this.description = description;
}
@PublicAPI(usage = ACCESS)
public JavaClass getTargetClass() {
return targetClass;
}
@Override
public String getDescription() {
return description;
}
@Override
@PublicAPI(usage = ACCESS)
public int compareTo(Dependency o) {
return ComparisonChain.start()
.compare(lineNumber, o.lineNumber)
.compare(getDescription(), o.getDescription())
.result();
}
@Override
public int hashCode() {
return Objects.hash(originClass, targetClass, lineNumber, description);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final Dependency other = (Dependency) obj;
return Objects.equals(this.originClass, other.originClass)
&& Objects.equals(this.targetClass, other.targetClass)
&& Objects.equals(this.lineNumber, other.lineNumber)
&& Objects.equals(this.description, other.description);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("originClass", originClass)
.add("targetClass", targetClass)
.add("lineNumber", lineNumber)
.add("description", description)
.toString();
}
@PublicAPI(usage = ACCESS)
public static JavaClasses toTargetClasses(Iterable<Dependency> dependencies) {
Set<JavaClass> classes = new HashSet<>();
for (Dependency dependency : dependencies) {
classes.add(dependency.getTargetClass());
}
return JavaClasses.of(classes);
}
}