/** * 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.commons.visitors; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; import org.whole.lang.commons.factories.CommonsEntityFactory; import org.whole.lang.commons.model.Resolver; import org.whole.lang.commons.model.VarType; import org.whole.lang.commons.parsers.CommonsDataTypePresentationParser; import org.whole.lang.model.IEntity; import org.whole.lang.model.adapters.IEntityAdapter; import org.whole.lang.operations.ContentAssistOperation; import org.whole.lang.reflect.EntityDescriptor; import org.whole.lang.reflect.ILanguageKit; import org.whole.lang.reflect.ReflectionFactory; /** * @author Riccardo Solmi, Enrico Persiani */ public class CommonsContentAssistVisitor extends CommonsIdentityVisitor { public ContentAssistOperation getOperation() { return (ContentAssistOperation) super.getOperation(); } protected IEntity getSelectedEntity() { return getOperation().getSelectedEntity(); } public Set<EntityDescriptor<?>> getAllAssignableTo(EntityDescriptor<?> ed) { Set<EntityDescriptor<?>> assignableSet = ed.getLanguageConcreteSubtypes(); for (ILanguageKit languageKit : ReflectionFactory.getLanguageKits(true)) { for (EntityDescriptor<?> candidateEd : languageKit.getEntityDescriptorEnum()) if (ed.isPlatformSupertypeOf(candidateEd)) assignableSet.add(candidateEd); } return assignableSet; } public void visit(VarType entity) { try { IEntity variableEntity = entity.wGetParent(); IEntity variableEntityParent = variableEntity.wGetParent(); Set<EntityDescriptor<?>> assignableSet = getAllAssignableTo( variableEntityParent.wGetEntityDescriptor(variableEntity)); assignableSet.remove(entity.getValue()); List<VarType> assignableEntities = new ArrayList<VarType>(assignableSet.size()); for (EntityDescriptor<?> ed : assignableSet) assignableEntities.add(CommonsEntityFactory.instance.createVarType(ed)); Collections.sort(assignableEntities, new Comparator<VarType>() { public int compare(VarType e1, VarType e2) { return CommonsDataTypePresentationParser.unparseEntityDescriptor(e1.getValue()).compareToIgnoreCase(CommonsDataTypePresentationParser.unparseEntityDescriptor(e2.getValue())); } }); getOperation().setResult(assignableEntities.toArray(new IEntity[0])); } catch (Exception e) { // do nothing on error } } @SuppressWarnings("rawtypes") @Override public void visit(Resolver entity) { IEntity parent = entity.wGetParent(); //FIXME StackOverflow WAS if (EntityUtils.isResolver(parent)) if (parent.wGetLanguageKit().equals(entity.wGetLanguageKit())) return; IEntityAdapter adapter = null; //FIXME workaround to get the entity's adapter if (parent instanceof Collection) { for (Object child : (Collection) parent) if (child instanceof IEntityAdapter && entity.equals(((IEntityAdapter) child).wGetAdaptee(false))) { adapter = (IEntityAdapter) child; break; } } else { for (Method method : parent.getClass().getMethods()) if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { try { Object child = method.invoke(parent, new Object[0]); if (child instanceof IEntityAdapter && entity.equals(((IEntityAdapter) child).wGetAdaptee(false))) { adapter = (IEntityAdapter) child; break; } } catch (Exception e) { } } } //FIXME end workaround if (adapter != null) getOperation().stagedVisit(adapter); else if (parent.wGetLanguageKit().isDynamic()) getOperation().getVisitor(parent, getOperation().getStage()).visit(entity); } }