blob: 3c10f773e0a0ca74b5c2d2330a8965ae9f4c90b2 [file] [log] [blame]
/**
********************************************************************************
* Copyright (c) 2019, 2020 Robert Bosch GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Robert Bosch GmbH - initial API and implementation
********************************************************************************
*/
package org.eclipse.app4mc.validation.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.app4mc.validation.annotation.Profile;
import org.eclipse.app4mc.validation.annotation.ProfileGroup;
import org.eclipse.app4mc.validation.annotation.ValidationGroup;
import org.eclipse.app4mc.validation.core.IProfile;
import org.eclipse.app4mc.validation.core.IValidation;
import org.eclipse.app4mc.validation.core.Severity;
/**
* A cache object for a validation profile
*/
public class CachedProfile {
private final Class<? extends IProfile> profileClass;
private final CachedProfile parentProfile;
private final String name;
private final String description;
private final Map<Class<? extends IProfile>, CachedProfile> profiles = new HashMap<>();
private final Map<Class<? extends IValidation>, CachedValidator> validations = new HashMap<>();
public CachedProfile(final Class<? extends IProfile> profileClass) {
this(profileClass, null);
}
public CachedProfile(final Class<? extends IProfile> profileClass, final CachedProfile parent) {
super();
if (profileClass == null) {
throw new IllegalArgumentException("Loading aborted - Undefined profile class (null)");
}
this.profileClass = profileClass;
this.parentProfile = parent;
Profile profile = profileClass.getAnnotation(Profile.class);
name = (profile != null) ? profile.name() : profileClass.getSimpleName();
description = (profile != null) ? profile.description() : "";
List<Class<? extends IProfile>> forbiddenClasses = forbiddenSubProfileClasses();
ProfileGroup[] profileGroupList = profileClass.getAnnotationsByType(ProfileGroup.class);
for (ProfileGroup pGroup : profileGroupList) {
for (Class<? extends IProfile> pClass : pGroup.profiles()) {
if (pClass == null) {
throw new IllegalArgumentException(
"Loading aborted - Undefined sub profile class (null)");
}
if (forbiddenClasses.contains(pClass)) {
throw new IllegalArgumentException(
"Loading aborted - Cycle detected: " + pClass);
}
profiles.put(pClass, new CachedProfile(pClass, this));
}
}
ValidationGroup[] validationGroupList = profileClass.getAnnotationsByType(ValidationGroup.class);
for (ValidationGroup vGroup : validationGroupList) {
for (Class<? extends IValidation> vClass : vGroup.validations()) {
if (vClass == null) {
throw new IllegalArgumentException(
"Loading aborted - Undefined validation class (null)");
}
validations.put(vClass, new CachedValidator(vClass, vGroup.severity()));
}
}
}
private List<Class<? extends IProfile>> forbiddenSubProfileClasses() {
List<Class<? extends IProfile>> classes = new ArrayList<>();
for (CachedProfile profile = this; profile != null; profile = profile.getParentProfile()) {
Class<? extends IProfile> pc = profile.getProfileClass();
if (pc != null) classes.add(pc);
}
return classes;
}
// *** public getters ***
public CachedProfile getParentProfile() {
return parentProfile;
}
public Class<? extends IProfile> getProfileClass() {
return profileClass;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public Map<Class<? extends IProfile>, CachedProfile> getCachedProfiles() {
return profiles;
}
public Map<Class<? extends IValidation>, CachedValidator> getCachedValidations() {
return validations;
}
public Map<Class<? extends IValidation>, Severity> getAllValidations() {
Map<Class<? extends IValidation>, Severity> resultMap = new HashMap<>();
addAllValidations(this, resultMap);
return resultMap;
}
private void addAllValidations(final CachedProfile profile, final Map<Class<? extends IValidation>, Severity> resultMap) {
// add contained validations
for (CachedValidator cachedValidator : profile.getCachedValidations().values()) {
Class<? extends IValidation> validatorClass = cachedValidator.getValidatorClass();
Severity validatorSeverity = cachedValidator.getSeverity();
Severity oldSeverity = resultMap.get(validatorClass);
if (oldSeverity == null || oldSeverity.ordinal() < validatorSeverity.ordinal()) {
// insert: class -> higher severity
resultMap.put(validatorClass, validatorSeverity);
}
}
// add validations of contained profiles (recursive)
for (CachedProfile subProfile : profile.getCachedProfiles().values()) {
addAllValidations(subProfile, resultMap);
}
}
}