/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* 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 org.kie.workbench.common.stunner.core.definition.adapter;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.kie.workbench.common.stunner.core.api.FactoryManager;
import org.kie.workbench.common.stunner.core.definition.adapter.binding.BindableAdapterUtils;
import org.kie.workbench.common.stunner.core.definition.adapter.binding.HasInheritance;
import org.kie.workbench.common.stunner.core.definition.morph.MorphDefinition;
import org.kie.workbench.common.stunner.core.definition.morph.MorphProperty;
import org.kie.workbench.common.stunner.core.definition.property.PropertyMetaTypes;
import org.kie.workbench.common.stunner.core.util.DefinitionUtils;
public abstract class BindableMorphAdapter<S> extends AbstractMorphAdapter<S> {
public BindableMorphAdapter(final DefinitionUtils definitionUtils,
final FactoryManager factoryManager) {
super(definitionUtils,
factoryManager);
}
protected abstract <T> T doMerge(final S source,
final T result);
@Override
@SuppressWarnings("unchecked")
protected <T> T doMerge(final S source,
final MorphDefinition morphDefinition,
final T result) {
if (definitionUtils.isNonePolicy(morphDefinition)) {
return result;
}
if (definitionUtils.isDefaultPolicy(morphDefinition)) {
final Object nameProperty = getDefinitionManager().adapters().forDefinition().getMetaProperty(PropertyMetaTypes.NAME,
source);
final Object targetNameProperty = getDefinitionManager().adapters().forDefinition().getMetaProperty(PropertyMetaTypes.NAME,
result);
final Object namePropertyValue = getDefinitionManager().adapters().forProperty().getValue(nameProperty);
getDefinitionManager().adapters().forProperty().setValue(targetNameProperty,
namePropertyValue);
return result;
}
return doMerge(source,
result);
}
@Override
public <T> Iterable<MorphProperty> getMorphProperties(final T definition) {
return getMorphPropertiesForType(definition.getClass());
}
@Override
public <T> Iterable<MorphDefinition> getMorphDefinitions(final T definition) {
return getMorphDefinitionsForType(definition.getClass());
}
public Iterable<MorphDefinition> getMorphDefinitionsForType(final Class<?> type) {
final String dId = getDefinitionId(type);
final String baseId = getBaseDefinitionId(type);
return super.getMorphDefinitions(dId,
baseId);
}
public <T> Iterable<MorphProperty> getMorphPropertiesForType(final Class<?> type) {
final String dId = getDefinitionId(type);
final String baseId = getBaseDefinitionId(type);
return super.getMorphProperties(dId,
baseId);
}
public <T> Iterable<String> getTargetsForType(final Class<?> type) {
final String dId = getDefinitionId(type);
final String baseId = getBaseDefinitionId(type);
return getTargets(type,
dId,
baseId);
}
@Override
public boolean isPojoModel() {
return true;
}
@Override
protected Iterable<String> getTargets(final Class<?> type,
final String definitionId,
final String baseId) {
final Iterable<String> superTargets = super.getTargets(type,
definitionId,
baseId);
if (null != superTargets && superTargets.iterator().hasNext()) {
final Set<String> result = new LinkedHashSet<>();
for (final String s : superTargets) {
final String[] types = getTypes(type,
s);
if (null != types && types.length > 0) {
Collections.addAll(result,
types);
} else {
result.add(s);
}
}
return result;
}
return null;
}
protected String[] getTypes(final Class<?> adapterType,
final String baseType) {
final DefinitionAdapter<Object> definitionAdapter = getDefinitionManager().adapters().registry().getDefinitionAdapter(adapterType);
if (definitionAdapter instanceof HasInheritance) {
return ((HasInheritance) definitionAdapter).getTypes(baseType);
}
return null;
}
@SuppressWarnings("unchecked")
protected String getBaseDefinitionId(final Class<?> type) {
final DefinitionAdapter<Object> definitionAdapter = getDefinitionManager().adapters().registry().getDefinitionAdapter(type);
if (definitionAdapter instanceof HasInheritance) {
return ((HasInheritance) definitionAdapter).getBaseType(type);
}
return null;
}
protected String getDefinitionId(final Class<?> type) {
return BindableAdapterUtils.getDefinitionId(type);
}
}