/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.isis.core.metamodel.facets.object;
import org.apache.isis.applib.RecreatableDomainObject;
import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.annotation.DomainObjectLayout;
import org.apache.isis.applib.annotation.Nature;
import org.apache.isis.applib.annotation.ViewModel;
import org.apache.isis.applib.annotation.ViewModelLayout;
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facetapi.MetaModelValidatorRefiner;
import org.apache.isis.core.metamodel.facets.Annotations;
import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorForValidationFailures;
public class ViewModelSemanticCheckingFacetFactory extends FacetFactoryAbstract implements MetaModelValidatorRefiner {
public ViewModelSemanticCheckingFacetFactory() {
super(FeatureType.OBJECTS_ONLY);
}
private final MetaModelValidatorForValidationFailures validator = new MetaModelValidatorForValidationFailures();
@Override
public void process(final ProcessClassContext processClassContext) {
// disable by default
final boolean enable = getConfiguration().getBoolean(
"isis.reflector.facets.ViewModelSemanticCheckingFacetFactory.enable", false);
if(!enable) {
return;
}
final Class<?> cls = processClassContext.getCls();
final DomainObjectLayout domainObjectLayout = Annotations.getAnnotation(cls, DomainObjectLayout.class);
final ViewModelLayout viewModelLayout = Annotations.getAnnotation(cls, ViewModelLayout.class);
final DomainObject domainObject = Annotations.getAnnotation(cls, DomainObject.class);
final ViewModel viewModel = Annotations.getAnnotation(cls, ViewModel.class);
final boolean implementsViewModel = org.apache.isis.applib.ViewModel.class.isAssignableFrom(cls);
final boolean implementsRecreatableDomainObject = org.apache.isis.applib.RecreatableDomainObject.class.isAssignableFrom(cls);
final boolean annotatedWithDomainObjectLayout = domainObjectLayout != null;
final boolean annotatedWithViewModelLayout = viewModelLayout != null;
final boolean annotatedWithDomainObject = domainObject != null;
final boolean annotatedWithViewModel = viewModel != null;
if(implementsViewModel && implementsRecreatableDomainObject) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %s should not implement both %s and %s interfaces (implement one or the other)",
cls.getName(),
org.apache.isis.applib.ViewModel.class.getSimpleName(),
org.apache.isis.applib.RecreatableDomainObject.class.getSimpleName());
}
if(implementsViewModel && annotatedWithDomainObject) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not implement %2$s and be annotated with @%3$s (annotate with %4$s instead of %2$s, or implement %5s instead of %2$s)",
cls.getName(),
org.apache.isis.applib.ViewModel.class.getSimpleName(),
DomainObject.class.getSimpleName(),
ViewModel.class.getSimpleName(),
RecreatableDomainObject.class.getSimpleName()
);
}
if(implementsViewModel && annotatedWithDomainObjectLayout) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not implement %2$s and be annotated with @%3$s (annotate with @%4$s instead of %3$s, or implement %5$s instead of %2$s)",
cls.getName(),
org.apache.isis.applib.ViewModel.class.getSimpleName(),
DomainObjectLayout.class.getSimpleName(),
ViewModelLayout.class.getSimpleName(),
RecreatableDomainObject.class.getSimpleName());
}
if(annotatedWithViewModel && implementsRecreatableDomainObject) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not be annotated with @%2$s but implement @%3$s (implement %4$s instead of %3$s, or annotate with @%5$s with nature of %6s, %7s or %8s instead of annotating with @%2$s)",
cls.getName(),
org.apache.isis.applib.annotation.ViewModel.class.getSimpleName(),
org.apache.isis.applib.RecreatableDomainObject.class.getSimpleName(),
org.apache.isis.applib.ViewModel.class.getName(),
org.apache.isis.applib.annotation.DomainObject.class.getName(),
Nature.VIEW_MODEL,
Nature.INMEMORY_ENTITY,
Nature.EXTERNAL_ENTITY
);
}
if(annotatedWithViewModel && annotatedWithDomainObject) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not be annotated with both @%2$s and @%3$s (annotate with one or the other)",
cls.getName(),
org.apache.isis.applib.annotation.ViewModel.class.getSimpleName(),
org.apache.isis.applib.annotation.DomainObject.class.getSimpleName());
}
if(annotatedWithViewModel && annotatedWithDomainObjectLayout) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not be annotated with both @%2$s and @%3$s (annotate with @%4$s instead of @%3$s, or annotate with @%5$s instead of @%2$s)",
cls.getName(),
org.apache.isis.applib.annotation.ViewModel.class.getSimpleName(),
DomainObjectLayout.class.getSimpleName(),
ViewModelLayout.class.getSimpleName(),
DomainObject.class.getSimpleName());
}
if(annotatedWithViewModelLayout && implementsRecreatableDomainObject) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not be annotated with @%2$s but implement @%3$s (implement %4$s instead of %3$s, or annotate with %5$s instead of %2$s)",
cls.getName(),
org.apache.isis.applib.annotation.ViewModelLayout.class.getSimpleName(),
RecreatableDomainObject.class.getSimpleName(),
org.apache.isis.applib.ViewModel.class.getSimpleName(),
DomainObjectLayout.class.getSimpleName());
}
if(annotatedWithViewModelLayout && annotatedWithDomainObject) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not be annotated with @%2$s and also be annotated with @%3$s (annotate with @%4$s instead of @%3$s, or instead annotate with @%5$s instead of @%2$s)",
cls.getName(),
org.apache.isis.applib.annotation.ViewModelLayout.class.getSimpleName(),
DomainObject.class.getSimpleName(),
org.apache.isis.applib.annotation.ViewModel.class.getSimpleName(),
DomainObjectLayout.class.getSimpleName());
}
if(annotatedWithViewModelLayout && annotatedWithDomainObjectLayout) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not be annotated with both @%2$s and @%3$s (annotate with one or the other)",
cls.getName(),
org.apache.isis.applib.annotation.ViewModel.class.getSimpleName(),
DomainObjectLayout.class.getSimpleName(),
ViewModelLayout.class.getSimpleName());
}
if( annotatedWithDomainObject &&
(domainObject.nature() == Nature.NOT_SPECIFIED || domainObject.nature() == Nature.JDO_ENTITY) &&
implementsRecreatableDomainObject) {
validator.addFailure(
"Inconsistent view model / domain object semantics; %1$s should not be annotated with @%2$s with nature of %3$s and also implement %4$s (specify a nature of %5$s, %6$s or %7$s)",
cls.getName(),
DomainObject.class.getSimpleName(),
domainObject.nature(),
org.apache.isis.applib.RecreatableDomainObject.class.getSimpleName(),
Nature.EXTERNAL_ENTITY, Nature.INMEMORY_ENTITY, Nature.VIEW_MODEL);
}
}
@Override
public void refineMetaModelValidator(final MetaModelValidatorComposite metaModelValidator, final IsisConfiguration configuration) {
metaModelValidator.add(validator);
}
}