/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.semantics.util;
import java.util.List;
import org.whole.lang.bindings.BindingManagerFactory;
import org.whole.lang.bindings.IBindingManager;
import org.whole.lang.commons.factories.CommonsEntityFactory;
import org.whole.lang.commons.parsers.CommonsDataTypePersistenceParser;
import org.whole.lang.commons.reflect.CommonsEntityDescriptorEnum;
import org.whole.lang.factories.GenericEntityFactory;
import org.whole.lang.factories.IEntityFactory;
import org.whole.lang.factories.RegistryConfigurations;
import org.whole.lang.iterators.IEntityIterator;
import org.whole.lang.iterators.IteratorFactory;
import org.whole.lang.matchers.Matcher;
import org.whole.lang.model.IEntity;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.reflect.FeatureDescriptor;
import org.whole.lang.reflect.ILanguageKit;
import org.whole.lang.reflect.ReflectionFactory;
import org.whole.lang.resources.FunctionLibraryRegistry;
import org.whole.lang.semantics.factories.SemanticsEntityFactory;
import org.whole.lang.semantics.model.EntityType;
import org.whole.lang.semantics.model.LocalIdentifier;
import org.whole.lang.semantics.model.Name;
import org.whole.lang.semantics.model.SemanticFunction;
import org.whole.lang.semantics.model.SemanticFunctions;
import org.whole.lang.semantics.model.SemanticTheory;
import org.whole.lang.semantics.model.StructuredVariable;
import org.whole.lang.semantics.model.Variable;
import org.whole.lang.semantics.reflect.SemanticsEntityDescriptorEnum;
import org.whole.lang.semantics.reflect.SemanticsFeatureDescriptorEnum;
import org.whole.lang.util.DataTypeUtils;
import org.whole.lang.util.EntityUtils;
import org.whole.lang.util.FreshNameGenerator;
import org.whole.lang.util.IRunnable;
import org.whole.lang.util.ResourceUtils;
import org.whole.lang.util.StringUtils;
import org.whole.lang.visitors.GenericIdentityVisitor;
import org.whole.lang.visitors.VisitException;
/**
* @author Riccardo Solmi
*/
public class SemanticsUtils {
public static final String USE_IDENTIFIER_SEMANTICS = "USE_IDENTIFIER_SEMANTICS";
public static IEntityIterator<IEntity> typeCastIterator() {
return IteratorFactory.singleValuedRunnableIterator(new IRunnable() {
public void run(IEntity selfEntity, IBindingManager bm, IEntity... arguments) {
bm.setResult(BindingManagerFactory.instance.createSpecificValue(selfEntity));
}
});
}
public static IEntityIterator<IEntity> typeCastIterator(final String entityTypeUri) {
return IteratorFactory.singleValuedRunnableIterator(new IRunnable() {
public void run(IEntity selfEntity, IBindingManager bm, IEntity... arguments) {
//TODO String contextUri = bm.wIsSet("contextURI") ? bm.wStringValue("contextURI") : null;
EntityDescriptor<?> toEd = CommonsDataTypePersistenceParser.parseEntityDescriptor(entityTypeUri);
bm.setResult(DataTypeUtils.convertCloneIfParented(selfEntity, toEd));
}
});
}
public static IEntityIterator<IEntity> semanticsTheoriesIterator() {
return IteratorFactory.javaCollectionIterator(
FunctionLibraryRegistry.instance().getResources(false, ResourceUtils.SIMPLE_COMPARATOR));
}
public static IEntity getSemanticTheory(String contextURI, String theoryURI, boolean loadOnDemand) {
return theoryURI != null ? FunctionLibraryRegistry.instance().getResourceModel(theoryURI, loadOnDemand, contextURI) : null;
}
public static boolean abstractFilter(EntityDescriptor<?> ed, boolean excludeAbstract) {
return !(ed.isAbstract() && excludeAbstract);
}
public static IEntity getEntitiesUri(IEntity type) {
if (type == null)
return BindingManagerFactory.instance.createTuple();
else if (Matcher.matchImpl(SemanticsEntityDescriptorEnum.LanguageType, type)) {
IEntity result = BindingManagerFactory.instance.createTuple();
String languageUri = type.wStringValue();
ILanguageKit languageKit = ReflectionFactory.getLanguageKit(languageUri, false, null);
if (languageKit != null)
for (EntityDescriptor<?> ed : languageKit.getEntityDescriptorEnum())
result.wAdd(BindingManagerFactory.instance.createValue(ed.getURI()));
return result;
} else if (Matcher.matchImpl(SemanticsEntityDescriptorEnum.EntityType, type))
try {
return getEntitiesUri(CommonsDataTypePersistenceParser.parseEntityDescriptor(type.wStringValue()));
} catch (IllegalArgumentException e) {
return BindingManagerFactory.instance.createTuple();
}
else
return getEntitiesUri(type.wGetEntityDescriptor());
}
public static IEntity getEntitiesUri(EntityDescriptor<?> ed) {
IEntity result = BindingManagerFactory.instance.createTuple();
if (ed.getEntityKind().isSimple()) {
List<FeatureDescriptor> fdEnum = ed.getEntityFeatureDescriptors();
for (FeatureDescriptor fd : fdEnum)
result.wAdd(BindingManagerFactory.instance.createValue(fd.getURI()));
}
return result;
}
public static IEntity getFeaturesUri(IEntity termOrEntityType) {
if (Matcher.matchImpl(SemanticsEntityDescriptorEnum.EntityType, termOrEntityType))
try {
return getFeaturesUri(
CommonsDataTypePersistenceParser.parseEntityDescriptor(termOrEntityType.wStringValue()));
} catch (IllegalArgumentException e) {
return BindingManagerFactory.instance.createTuple();
}
else
return getFeaturesUri(termOrEntityType.wGetEntityDescriptor());
}
public static IEntity getFeaturesUri(String edUri) {
return getFeaturesUri(
CommonsDataTypePersistenceParser.parseEntityDescriptor(edUri));
}
public static IEntity getFeaturesUri(EntityDescriptor<?> ed) {
IEntity result = BindingManagerFactory.instance.createTuple();
if (ed.getEntityKind().isSimple()) {
List<FeatureDescriptor> fdEnum = ed.getEntityFeatureDescriptors();
for (FeatureDescriptor fd : fdEnum)
result.wAdd(BindingManagerFactory.instance.createValue(fd.getURI()));
}
return result;
}
public static IEntity createShallowCloneEntity(IEntity selfEntity) {
EntityDescriptor<?> ed = selfEntity.wGetEntityDescriptor();
return createShallowMigrateEntity(selfEntity, ed);
}
public static IEntity createShallowMigrateEntity(IEntity selfEntity, String targetUri) {
String edUri = ResourceUtils.hasFragmentPart(targetUri) ?
targetUri : targetUri+"#"+selfEntity.wGetEntityDescriptor().getName();
EntityDescriptor<?> ed = CommonsDataTypePersistenceParser.getEntityDescriptor(edUri, false, null);
if (ed == null)
throw new IllegalArgumentException("The migration target entity is not available: "+targetUri);
return createShallowMigrateEntity(selfEntity, ed);
}
public static IEntity createShallowMigrateEntity(IEntity selfEntity, EntityDescriptor<?> targetEd) {
IEntityFactory gef = GenericEntityFactory.instance(RegistryConfigurations.RESOLVER);
switch (targetEd.getEntityKind()) {
case DATA:
return gef.create(targetEd, selfEntity.wGetValue());
case COMPOSITE:
// return gef.create(ed, bindings);
default:
case SIMPLE:
return gef.create(targetEd);
}
}
//TODO test
public static IEntity createMigrateEntityWithUri(IEntity selfEntity, String sourceUri, String targetUri) {
final EntityDescriptor<?> selfEd = selfEntity.wGetEntityDescriptor();
if (selfEd.getDataKind().isString()) {
String sourceValue = selfEntity.wStringValue();
if (sourceValue.startsWith(sourceUri))
GenericEntityFactory.instance.create(selfEd,
sourceValue.length() == sourceUri.length() ?
targetUri : targetUri + sourceValue.substring(sourceUri.length()));
}
return BindingManagerFactory.instance.createVoid();
}
public static IEntity createTerm(String edUri, FreshNameGenerator nameGenerator) {
EntityDescriptor<?> ed = CommonsDataTypePersistenceParser.getEntityDescriptor(edUri, false, null);
if (ed == null || (!EntityUtils.isSimple(ed) && !EntityUtils.isFragment(ed)))
return SemanticsEntityFactory.instance.createEntityType(edUri);
int size = ed.featureSize();
IEntity[] values = new IEntity[size];
SemanticsEntityFactory sf = SemanticsEntityFactory.instance;
for (int i=0; i<size; i++) {
FeatureDescriptor fd = ed.getEntityFeatureDescriptor(i);
values[i] = sf.buildTypedVariable()
.set(SemanticsFeatureDescriptorEnum.variable,
sf.createVariable(nameGenerator.nextFreshName(fd.getName())))
.set(SemanticsFeatureDescriptorEnum.signature,
sf.createEntityType(fd.getEntityDescriptor().toString()))
.getResult();
}
return CommonsEntityFactory.instance.createStageUpFragment(
GenericEntityFactory.instance.create(ed, values).wGetAdapter(CommonsEntityDescriptorEnum.Any));
}
public static IEntity createTypedVariable(LocalIdentifier variable, FreshNameGenerator nameGenerator) {
return variable instanceof StructuredVariable ?
createTypedVariable((StructuredVariable) variable, nameGenerator) :
createTypedVariable((Variable) variable, nameGenerator);
}
public static IEntity createTypedVariable(StructuredVariable variable, FreshNameGenerator nameGenerator) {
SemanticsEntityFactory sf = SemanticsEntityFactory.instance;
return sf.createTypedVariable(
EntityUtils.clone(variable.getVariable()),
EntityUtils.clone(variable.getIndex()),
EntityUtils.clone(variable.getTime()),
sf.createEntityType(EntityUtils.getFormalEntityDescriptor(variable).toString()));
}
public static IEntity createTypedVariable(Variable variable, FreshNameGenerator nameGenerator) {
SemanticsEntityFactory sf = SemanticsEntityFactory.instance;
return sf.buildTypedVariable()
.set(SemanticsFeatureDescriptorEnum.variable, EntityUtils.clone(variable))
.set(SemanticsFeatureDescriptorEnum.signature,
sf.createEntityType(variable.wGetParent().wGetEntityDescriptor(variable).toString()))
.getResult();
}
public static IEntity createTypedVariable(EntityType type, FreshNameGenerator nameGenerator) {
SemanticsEntityFactory sf = SemanticsEntityFactory.instance;
return sf.buildTypedVariable()
.set(SemanticsFeatureDescriptorEnum.variable,
sf.createVariable(nameGenerator.nextFreshName(StringUtils.toLowerPrefix(ResourceUtils.stripResourcePart(type.getValue())))))
.set(SemanticsFeatureDescriptorEnum.signature,
EntityUtils.clone(type))
.getResult();
}
public static SemanticFunction findSemanticFunction(SemanticTheory semanticTheory, String name) {
return findSemanticFunction(semanticTheory.getFunctions(), name);
}
public static SemanticFunction findSemanticFunction(SemanticFunctions semanticFunctions, String name) {
for (SemanticFunction sf : semanticFunctions) {
Name fName = sf.getName();
if (Matcher.matchImpl(SemanticsEntityDescriptorEnum.Name, fName) && fName.getValue().equals(name))
return sf;
}
return null;
}
public static boolean inStageDownContext(IEntity entity) {
IEntity ancestor = Matcher.findAncestor(new GenericIdentityVisitor() {
public void visit(IEntity entity) {
EntityDescriptor<?> ed = entity.wGetEntityDescriptor();
if (!(ed.equals(SemanticsEntityDescriptorEnum.ExecutionRule) ||
ed.equals(SemanticsEntityDescriptorEnum.InputBinding) ||
ed.equals(SemanticsEntityDescriptorEnum.FunctionApplication) ||
// ed.equals(SemanticsEntityDescriptorEnum.TypeCast) ||
ed.equals(SemanticsEntityDescriptorEnum.EnvironmentVariable) ||
ed.equals(SemanticsEntityDescriptorEnum.VariableValue) ||
EntityUtils.isFragment(ed)))
throw new VisitException();
}
}, entity);
return ancestor != null && (
Matcher.match(SemanticsEntityDescriptorEnum.VariableValue, ancestor) ||
EntityUtils.isStageUpFragment(ancestor));
}
}