/** * 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.builders; import java.util.Date; import java.util.Stack; import org.whole.lang.model.EnumValue; import org.whole.lang.reflect.EntityDescriptor; import org.whole.lang.reflect.FeatureDescriptor; import org.whole.lang.templates.ITemplate; /** * @author Enrico Persiani */ public class GenericEventTrackingBuilder extends GenericForwardStrategyBuilder { protected Stack<State> stateStack; public GenericEventTrackingBuilder(IBuilder builderStrategy) { this(builderStrategy, UNKNOWN); } public GenericEventTrackingBuilder(IBuilder builderStrategy, EntityDescriptor<?> ed) { this(builderStrategy, new State(ed, 0)); } public GenericEventTrackingBuilder(IBuilder builderStrategy, EntityDescriptor<?> ed, FeatureDescriptor fd) { this(builderStrategy, ed, ed.indexOf(fd)); } public GenericEventTrackingBuilder(IBuilder builderStrategy, EntityDescriptor<?> ed, int index) { this(builderStrategy, new State(ed, index)); } protected GenericEventTrackingBuilder(IBuilder builderStrategy, State initialState) { super(builderStrategy); this.stateStack = new Stack<State>(); this.stateStack.push(initialState); } protected void nextIndex() { stateStack.peek().nextIndex(); } protected void pushState(EntityDescriptor<?> ed) { stateStack.push(new State(ed, 0)); } protected void pushUnknownState() { stateStack.push(UNKNOWN); } protected void popState() { stateStack.pop(); } protected void setIndex(int index) { stateStack.peek().setIndex(index); } public EntityDescriptor<?> wGetEntityDescriptor() { return stateStack.peek().getEntityDescriptor(); } public int wCurrentIndexOf() { return stateStack.peek().getIndex(); } public FeatureDescriptor wCurrentGetFeatureDescriptor() { State state = stateStack.peek(); int index = state.getIndex(); return index == -1 ? null : state.getEntityDescriptor().getEntityFeatureDescriptor(index); } public void wEntity(EntityDescriptor<?> ed) { nextIndex(); super.wEntity(ed); } public void wEntity_(EntityDescriptor<?> ed) { pushState(ed); super.wEntity_(ed); } public void wEntity_(EntityDescriptor<?> ed, int initialCapacity) { pushState(ed); super.wEntity_(ed, initialCapacity); } public void _wEntity(EntityDescriptor<?> ed) { popState(); nextIndex(); super._wEntity(ed); } public void wEntity(EntityDescriptor<?> ed, boolean value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, byte value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, char value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, double value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, float value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, int value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, long value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, short value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, String value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, Date value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, EnumValue value) { nextIndex(); super.wEntity(ed, value); } public void wEntity(EntityDescriptor<?> ed, Object value) { nextIndex(); super.wEntity(ed, value); } public void wEntity() { nextIndex(); super.wEntity(); } public void wEntity_() { pushUnknownState(); super.wEntity_(); } public void _wEntity() { popState(); nextIndex(); super._wEntity(); } public void wDefault() { nextIndex(); super.wDefault(); } public void wFeature(int index) { setIndex(index); super.wFeature(index); } public void wFeature(FeatureDescriptor fd) { EntityDescriptor<?> ed = wGetEntityDescriptor(); if (ed != null) // state == UNKNOWN => ed == null setIndex(ed.indexOf(fd)); super.wFeature(fd); } public void wFeature(ITemplate pattern) { //TODO super.wFeature(pattern); } protected static final State UNKNOWN = new State(null, -1) { public void setIndex(int index) { } public void nextIndex() { } }; protected static class State { private final EntityDescriptor<?> ed; private int index; public State(EntityDescriptor<?> ed) { this(ed, 0); } public State(EntityDescriptor<?> ed, int index) { this.ed = ed; this.index = index; } public EntityDescriptor<?> getEntityDescriptor() { return ed; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public void nextIndex() { this.index++; } @Override public String toString() { return this == UNKNOWN ? "UNKNOWN" : ed.getName()+"@"+ (ed.getEntityKind().isComposite() ? Integer.toString(index) : ed.featureSize() > index ? ed.getEntityFeatureDescriptor(index).getName() : "???"); } } }