/*
* 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.progmodel;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.Lists;
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.factory.InstanceUtil;
import org.apache.isis.core.metamodel.facetapi.MetaModelValidatorRefiner;
import org.apache.isis.core.metamodel.facets.FacetFactory;
import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
import org.apache.isis.progmodels.dflt.ProgrammingModelFacetsJava5;
public abstract class ProgrammingModelAbstract implements ProgrammingModel {
private final List<FacetFactory> facetFactories = Lists.newArrayList();
private final List<Object> facetFactoryInstancesOrClasses = Lists.newLinkedList();
public static final String KEY_IGNORE_DEPRECATED = "isis.reflector.facets.ignoreDeprecated";
public enum DeprecatedPolicy {
IGNORE,
HONOUR;
public static DeprecatedPolicy parse(final IsisConfiguration configuration) {
boolean ignoreDep = configuration.getBoolean(KEY_IGNORE_DEPRECATED, false);
return ignoreDep ? IGNORE : HONOUR;
}
}
protected final DeprecatedPolicy deprecatedPolicy;
public ProgrammingModelAbstract(
final ProgrammingModelFacetsJava5.DeprecatedPolicy deprecatedPolicy) {
this.deprecatedPolicy = deprecatedPolicy;
}
@Override
public void init() {
initializeIfRequired();
}
private void initializeIfRequired() {
if(!facetFactories.isEmpty()) {
return;
}
initialize();
}
private void initialize() {
for (final Object factoryInstanceOrClass : facetFactoryInstancesOrClasses) {
final FacetFactory facetFactory = asFacetFactory(factoryInstanceOrClass);
facetFactories.add(facetFactory);
}
}
private static FacetFactory asFacetFactory(final Object factoryInstanceOrClass) {
if(factoryInstanceOrClass instanceof FacetFactory) {
return (FacetFactory) factoryInstanceOrClass;
} else {
@SuppressWarnings("unchecked") final
Class<? extends FacetFactory> factoryClass = (Class<? extends FacetFactory>) factoryInstanceOrClass;
return (FacetFactory) InstanceUtil.createInstance(factoryClass);
}
}
private void assertNotInitialized() {
if(!facetFactories.isEmpty()) {
throw new IllegalStateException("Programming model already initialized");
}
}
@Override
public final List<FacetFactory> getList() {
initializeIfRequired();
return Collections.unmodifiableList(facetFactories);
}
@Override
public final void addFactory(final Class<? extends FacetFactory> factoryClass) {
addFactory(factoryClass, Position.END);
}
@Override
public final void addFactory(final Class<? extends FacetFactory> factoryClass, final Position position) {
addFactory((Object)factoryClass, position);
}
@Override
public void addFactory(final FacetFactory facetFactory) {
addFactory(facetFactory, Position.END);
}
@Override
public void addFactory(final FacetFactory facetFactory, final Position position) {
addFactory((Object)facetFactory, position);
}
private void addFactory(final Object facetFactoryInstanceOrClass, final Position position) {
assertNotInitialized();
if(deprecatedPolicy == DeprecatedPolicy.IGNORE) {
if( facetFactoryInstanceOrClass instanceof FacetFactory) {
if(facetFactoryInstanceOrClass instanceof DeprecatedMarker) {
return;
}
} else if (facetFactoryInstanceOrClass instanceof Class) {
if(DeprecatedMarker.class.isAssignableFrom((Class)facetFactoryInstanceOrClass)) {
return;
}
}
}
switch (position){
case BEGINNING:
facetFactoryInstancesOrClasses.add(0, facetFactoryInstanceOrClass);
break;
case END:
facetFactoryInstancesOrClasses.add(facetFactoryInstanceOrClass);
}
}
@Override
public final void removeFactory(final Class<? extends FacetFactory> factoryClass) {
assertNotInitialized();
facetFactoryInstancesOrClasses.remove(factoryClass);
}
@Override
public void refineMetaModelValidator(final MetaModelValidatorComposite metaModelValidator, final IsisConfiguration configuration) {
for (final FacetFactory facetFactory : getList()) {
if(facetFactory instanceof MetaModelValidatorRefiner) {
final MetaModelValidatorRefiner metaModelValidatorRefiner = (MetaModelValidatorRefiner) facetFactory;
metaModelValidatorRefiner.refineMetaModelValidator(metaModelValidator, configuration);
}
}
}
}