/** * 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.contexts; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import org.whole.lang.builders.IteratorAdapter; import org.whole.lang.commands.ICommand; import org.whole.lang.commons.factories.CommonsEntityFactory; import org.whole.lang.events.IChangeEventHandler; import org.whole.lang.events.IRequestEventHandler; import org.whole.lang.matchers.GenericMatcher; import org.whole.lang.model.EnumValue; import org.whole.lang.model.IEntity; import org.whole.lang.model.IFragmentModel; import org.whole.lang.model.InternalIEntity; import org.whole.lang.reflect.EntityDescriptor; import org.whole.lang.reflect.EntityKinds; import org.whole.lang.reflect.FeatureDescriptor; import org.whole.lang.reflect.IEditorKit; import org.whole.lang.reflect.ILanguageKit; /** * @author Riccardo Solmi */ public abstract class AbstractEntityContext implements IEntityContext, InternalIEntity { // protected IModelIterator iterator = NullIterator.instance; //FIXME intensional iterators protected IEntity rootEntity; protected int rootIndex; protected IEntity entity; protected int index; protected int contextTime = Integer.MAX_VALUE; public AbstractEntityContext() { wSetRoot(CommonsEntityFactory.instance.createRootFragment(CommonsEntityFactory.instance.createResolver()), 0); } public AbstractEntityContext(IEntity rootEntity) { this(rootEntity, 0); } public AbstractEntityContext(IEntity rootEntity, int rootIndex) { wSetRoot(rootEntity, rootIndex); } protected abstract IEntity entityContext(IEntity entity); public Object wGetAdapter(Class<?> adapter) { if (adapter.equals(Iterator.class)) return new IteratorAdapter(this); return null; } public boolean wIsAdapter() { return wGetEntity().wIsAdapter(); } public <E extends IEntity> E wGetAdapter(EntityDescriptor<E> ed) { return wGetEntity().wGetAdapter(ed); } public IEntity wGetAdaptee(boolean force) { return wGetEntity().wGetAdaptee(false); } public <E extends IEntity> E wResolveWith(EntityDescriptor<E> ed) { return wGetEntity().wResolveWith(ed); } public IEntity wGetEntity() { return entity; } public int wGetIndex() { return index; } public void wSetEntity(IEntity entity) { this.entity = entity; } protected void wSetEntity(IEntity entity, int index) { this.entity = entity; this.index = index; } public void wSetRoot(IEntity rootEntity, int rootIndex) { wSetEntity(this.rootEntity = rootEntity, this.rootIndex = rootIndex); } public void wResetRoot() { wSetEntity(this.rootEntity, this.rootIndex); } public IEntity wGetResult() { IEntity result = rootEntity.wGet(rootIndex); rootEntity.wRemove(rootIndex); return result; } public void setContextTime(int contextTime) { this.contextTime = contextTime; childrenCache.clear(); entity = wGetVersion(entity, contextTime); } public void setContextTime(IEntityContext context) { setContextTime(context.wGetBindingTime()); } public void setContextTimeToEntityBindingTime() { setContextTime(wGetBindingTime()); } public int wGetBindingTime() { return wGetBindingCommand().getExecutionTime(); } public IEntity wGetVersion(int bindingTime) { return entityContext(wGetVersion(entity, bindingTime)); } public IEntity wGetVersion(IEntityContext other) { return wGetVersion(other.wGetBindingTime()); } public IEntity wGetPrevVersion() { return entityContext(wGetPrevVersion(entity)); } /* public IEntity wGetLastVersion() { return resultContext(entity.wGetLastVersion()); } */ public void wUndo() { entity.wGetModel().getCompoundModel().getHistoryManager().undo(); } public void wRedo() { entity.wGetModel().getCompoundModel().getHistoryManager().redo(); } public ILanguageKit wGetLanguageKit() { return entity.wGetLanguageKit(); } public IEditorKit wGetEditorKit() { return entity.wGetEditorKit(); } public EntityDescriptor<?> wGetEntityDescriptor() { return entity.wGetEntityDescriptor(); } public int wGetEntityOrd() { return entity.wGetEntityOrd(); } public EntityKinds wGetEntityKind() { return entity.wGetEntityKind(); } public Serializable wGetPid() { return entity.wGetPid(); } public void wSetPid(Serializable pid) { ((InternalIEntity) entity).wSetPid(pid); } // public int hashCode() { // return entity.hashCode(); // } // public boolean equals(Object obj) { // return entity.equals(obj); // } public int wHashCode() { return entity.wHashCode(); } public boolean wEquals(IEntity entity) { return entity.wEquals(entity); } public IEntity wGetRoot() { return entityContext(entity.wGetRoot()); } public final IEntity wGetParent() { return entityContext(wGetParentIEntity()); } public IEntity wGetParentIEntity() { return entity.wGetParent(); } public void wSetParent(IEntity parent) { ((InternalIEntity) entity).wSetParent(parent); } public void wRemoveParent(IEntity parent) { ((InternalIEntity) entity).wRemoveParent(parent); } public void wAddInverseAdjacent(IEntity inverseAdjacent) { ((InternalIEntity) entity).wAddInverseAdjacent(inverseAdjacent); } public void wRemoveInverseAdjacent(IEntity inverseAdjacent) { ((InternalIEntity) entity).wRemoveInverseAdjacent(inverseAdjacent); } public boolean wAdd(FeatureDescriptor fd, IEntity value, boolean forceUnique) { return entity.wAdd(fd, value, forceUnique); } public boolean wRemove(FeatureDescriptor fd, IEntity value) { return entity.wRemove(fd, value); } /* public IEntityContext wSetIterator(IModelIterator iterator) { this.iterator = iterator; return this; }*/ public void wParent() { IEntity child = entity; entity = wGetParentIEntity(); index = entity.wIndexOf(child);//wGetBindingCommand().getSourceIndex(); } public void wParent(EntityDescriptor<?> ed) { IEntity entityInScope = entity; do { entityInScope = entityInScope.wGetParent(); } while (entityInScope.wGetEntityDescriptor().equals(ed)); entity = entityInScope; index = 0; } public void wChild() { entity = wGetIEntity(index); index = 0; } public void wFirstChild() { entity = wGetIEntity(0); index = 0; } public void wLastChild() { entity = wGetIEntity(wSize()-1); index = 0; } public boolean wHasNext() { return index < wSize(); // return iterator.wHasNext(); } public void wNext() { index++; // wSetEntity(iterator.wNext()); } public void wFeature(int index) { this.index = index; } public void wFeature(FeatureDescriptor feature) { index = wIndexOf(feature); } public void wPrune() { // iterator.wPrune(); } public FeatureDescriptor wCurrentGetFeatureDescriptor() { return wGetFeatureDescriptor(index); } public EntityDescriptor<?> wCurrentGetEntityDescriptor() { return wGetEntityDescriptor(index); } public int wCurrentIndexOf() { return index; } public boolean wCurrentAdd(IEntity entity) { wAdd(index, entity); return true; } public void wCurrentRemove() { wRemove(index); } public IEntity wCurrentGet() { return wGet(index); } public void wCurrentSet(IEntity entity) { wSet(index, entity); } public int wIndexOf(IEntityContext value) { return wIndexOf(((AbstractEntityContext) value).wGetEntity()); } public FeatureDescriptor wGetFeatureDescriptor(IEntityContext child) { return wGetFeatureDescriptor(((AbstractEntityContext) child).wGetEntity()); } public void wSet(IEntityContext oldChild, IEntityContext newChild) { wSet(((AbstractEntityContext) oldChild).wGetEntity(), ((AbstractEntityContext) newChild).wGetEntity()); } public boolean wContains(IEntity child) { return entity.wContains(child); } public int wIndexOf(IEntity value) { return entity.wIndexOf(value); } public FeatureDescriptor wGetFeatureDescriptor(IEntity child) { return entity.wGetFeatureDescriptor(child); } public EntityDescriptor<?> wGetEntityDescriptor(IEntity child) { return entity.wGetEntityDescriptor(child); } public EntityDescriptor<?> wGetEntityDescriptor(int index) { return entity.wGetEntityDescriptor(index); } public EntityDescriptor<?> wGetEntityDescriptor(FeatureDescriptor fd) { return entity.wGetEntityDescriptor(fd); } public boolean wAdd(IEntity child) { return entity.wAdd(child); } public boolean wRemove(IEntity child) { return entity.wRemove(child); } public IEntity wGet(IEntity child) { return entity.wGet(child); } public boolean wSet(IEntity oldChild, IEntity newChild) { return entity.wSet(oldChild, newChild); } public boolean wIsSet(IEntity child) { return entity.wIsSet(child); } public void wUnset(IEntity child) { entity.wUnset(child); } public boolean wIsEmpty() { return entity.wIsEmpty(); } public int wSize() { return entity.wSize(); } public int wAdjacentSize() { return entity.wAdjacentSize(); } public int wInverseAdjacentSize() { return entity.wInverseAdjacentSize(); } public Iterable<IEntity> wInverseAdjacents() { return entity.wInverseAdjacents(); } public Set<FeatureDescriptor> wGetAspectualFeatureDescriptors() { return entity.wGetAspectualFeatureDescriptors(); } public boolean wContains(int index) { return entity.wContains(index); } public FeatureDescriptor wGetFeatureDescriptor(int index) { return entity.wGetFeatureDescriptor(index); } public void wAdd(int index, IEntityContext value) { wAdd(index, ((AbstractEntityContext) value).wGetEntity()); } public boolean wAdd(int index, IEntity value) { return entity.wAdd(index, value); } public boolean wRemove(int index) { return entity.wRemove(index); } public final IEntity wGet(int index) { return entityContext(wGetIEntity(index)); } protected IEntity wGetIEntity(int index) { return entity.wGet(index); } public void wSet(int index, IEntityContext value) { wSet(index, ((AbstractEntityContext) value).wGetEntity()); } public void/*boolean*/ wSet(int index, IEntity value) { /*return*/ entity.wSet(index, value); } public boolean wIsSet(int index) { return entity.wIsSet(index); } public void wUnset(int index) { entity.wUnset(index); } public boolean wContains(FeatureDescriptor feature) { return entity.wContains(feature); } public int wIndexOf(FeatureDescriptor feature) { return entity.wIndexOf(feature); } public boolean wRemove(FeatureDescriptor feature) { return entity.wRemove(feature); } public IEntity wGet(FeatureDescriptor feature) { return entityContext(entity.wGet(entity.wIndexOf(feature))); } public void wSet(FeatureDescriptor feature, IEntityContext value) { wSet(feature, ((AbstractEntityContext) value).wGetEntity()); } public void wSet(FeatureDescriptor feature, IEntity value) { entity.wSet(entity.wIndexOf(feature), value); } public boolean wIsSet(FeatureDescriptor feature) { return entity.wIsSet(feature); } public void wUnset(FeatureDescriptor feature) { entity.wUnset(feature); } public boolean wContainsValue(Object value) { return entity.wContainsValue(value); } public boolean wBooleanValue() { return entity.wBooleanValue(); } public byte wByteValue() { return entity.wByteValue(); } public char wCharValue() { return entity.wCharValue(); } public double wDoubleValue() { return entity.wDoubleValue(); } public float wFloatValue() { return entity.wFloatValue(); } public int wIntValue() { return entity.wIntValue(); } public long wLongValue() { return entity.wLongValue(); } public short wShortValue() { return entity.wShortValue(); } public String wStringValue() { return entity.wStringValue(); } public Date wDateValue() { return entity.wDateValue(); } public EnumValue wEnumValue() { return entity.wEnumValue(); } public Object wGetValue() { return entity.wGetValue(); } public void wSetValue(boolean value) { entity.wSetValue(value); } public void wSetValue(byte value) { entity.wSetValue(value); } public void wSetValue(char value) { entity.wSetValue(value); } public void wSetValue(double value) { entity.wSetValue(value); } public void wSetValue(float value) { entity.wSetValue(value); } public void wSetValue(int value) { entity.wSetValue(value); } public void wSetValue(long value) { entity.wSetValue(value); } public void wSetValue(short value) { entity.wSetValue(value); } public void wSetValue(String value) { entity.wSetValue(value); } public void wSetValue(Date value) { entity.wSetValue(value); } public void wSetValue(EnumValue value) { entity.wSetValue(value); } public void wSetValue(Object value) { entity.wSetValue(value); } public boolean wIsSet() { return entity.wIsSet(); } public void wUnset() { entity.wUnset(); } private Map<IEntity, List<IEntity>> childrenCache = new WeakHashMap<IEntity, List<IEntity>>(); protected IEntity wGetVersion(IEntity e, int contextTime) { ICommand cmd = ((InternalIEntity) e).wGetBindingCommand(); if (cmd.getKind().isComposite()) { List<IEntity> children = wIndexedFeatures(cmd.getSource(), contextTime); return children.get(cmd.getSourceIndex()); } else return cmd.getCommand(contextTime).getNewEntity(); } protected IEntity wGetPrevVersion(IEntity e) { ICommand cmd = ((InternalIEntity) e).wGetBindingCommand(); if (cmd.getKind().isComposite()) { IEntity source = cmd.getSource(); List<IEntity> children = wIndexedFeatures(source, ((InternalIEntity) source).wGetLastCommand().getPrevCommand().getExecutionTime()); return children.get(cmd.getSourceIndex()); } else return cmd.getPrevCommand().getNewEntity(); } @Deprecated public List<IEntity> wIndexedFeatures(IEntity e, int contextTime) { List<IEntity> result = childrenCache.get(e); if (result != null && this.contextTime == contextTime) return result; result = new ArrayList<IEntity>(e.wFeatures()); ICommand cmd = ((InternalIEntity) e).wGetLastCommand(); while (contextTime < cmd.getExecutionTime()) { switch (cmd.getKind()) { case ADD: result.remove(cmd.getSourceIndex()); break; case REMOVE: result.add(cmd.getSourceIndex(), cmd.getOldEntity()); break; case CHANGE: result.set(cmd.getSourceIndex(), cmd.getOldEntity()); break; } cmd = cmd.getPrevCommand(); } if (this.contextTime == contextTime) childrenCache.put(e, result); return result; } public IEntity wShallowClone() { return entityContext(((InternalIEntity) entity).wShallowClone()); } public IFragmentModel wGetModel() { return entity.wGetModel(); } public void wSetModel(IFragmentModel model) { ((InternalIEntity) entity).wSetModel(model); } public void wAddRequestEventHandler(IRequestEventHandler eventHandler) { entity.wAddRequestEventHandler(eventHandler); } public void wRemoveRequestEventHandler(IRequestEventHandler eventHandler) { entity.wRemoveRequestEventHandler(eventHandler); } public void wAddChangeEventHandler(IChangeEventHandler eventHandler) { entity.wAddChangeEventHandler(eventHandler); } public void wRemoveChangeEventHandler(IChangeEventHandler eventHandler) { entity.wRemoveChangeEventHandler(eventHandler); } @Deprecated public List<IEntity> wFeatures() { return entity.wFeatures(); } public Set<IEntity> wGetSharingSet() { return entity.wGetSharingSet(); } @Deprecated public void wAccept(GenericMatcher matcher, IEntity other) { entity.wAccept(matcher, other); } public ICommand wGetBindingCommand() { return ((InternalIEntity) entity).wGetBindingCommand(); } public void wSetBindingCommand(ICommand command) { ((InternalIEntity) entity).wSetBindingCommand(command); } public ICommand wGetLastCommand() { return ((InternalIEntity) entity).wGetBindingCommand(); } public ICommand wSetLastCommand(ICommand command) { return ((InternalIEntity) entity).wSetLastCommand(command); } }