001    /* EVolve - an Extensible Software Visualization Framework
002     * Copyright (C) 2001-2002 Qin Wang
003     *
004     * This library is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Library General Public
006     * License as published by the Free Software Foundation; either
007     * version 2 of the License, or (at your option) any later version.
008     *
009     * This library is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012     * Library General Public License for more details.
013     *
014     * You should have received a copy of the GNU Library General Public
015     * License along with this library; if not, write to the
016     * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017     * Boston, MA 02111-1307, USA.
018     */
019    
020    /*
021     * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
022     */
023    
024    package EVolve.data;
025    
026    import java.util.*;
027    
028    /**
029     * Element builder.
030     */
031    public abstract class ElementBuilder {
032        private static int typeCounter; // counter of element type
033    
034        private String elementName; // name of the elements
035        private String elementDescription; // description of the elements
036    
037        protected int elementType; // type of the elements
038        private ElementDefinition elementDefinition; // definition of the elements
039    
040        private ArrayList fieldDefinitionList; // field definitions
041    
042        private int entityCounter; // counter of entities
043        private String entityName; // name of the entity
044        private int[] field; // fields
045    
046        /**
047         * Creates an element builder.
048         *
049         * @param   elementName name of the elements
050         * @param   elementDescription description of the elements
051         */
052        protected ElementBuilder(String elementName, String elementDescription) {
053            this.elementName = elementName;
054            this.elementDescription = elementDescription;
055    
056            typeCounter++;
057            this.elementType = typeCounter;
058            this.elementDefinition = null;
059            this.fieldDefinitionList = new ArrayList();
060            this.entityCounter = -1;
061        }
062    
063        /**
064         * Initializes the element builders.
065         */
066        public static void init() {
067            typeCounter = -1;
068        }
069    
070        /**
071         * Builds the definition of a value field.
072         *
073         * @param   fieldName name of the field
074         * @param   fieldProperty property of the field
075         * @param   fieldDescription description of the field
076         * @return  the field definition
077         */
078        public FieldDefinition buildValueDefinition(String fieldName, String[] fieldProperty, String fieldDescription) {
079            assert(elementDefinition == null) : ("The definition of element " + elementName + " is already built, cannot add field definition to it.");
080    
081            FieldDefinition fieldDefinition = new FieldDefinition(fieldName, fieldDefinitionList.size(), -1, fieldDescription);
082            if (fieldProperty != null) {
083                for (int i = 0; i < fieldProperty.length; i++) {
084                    fieldDefinition.addProperty(fieldProperty[i]);
085                }
086            }
087            fieldDefinitionList.add(fieldDefinition);
088    
089            return fieldDefinition;
090        }
091    
092        /**
093         * Builds the definition of a reference field.
094         *
095         * @param   fieldName name of the field
096         * @param   referenceBuilder builder of the reference
097         * @param   fieldProperty property of the field
098         * @param   fieldDescription description of the field
099         * @return  the field definition
100         */
101        public FieldDefinition buildReferenceDefinition(String fieldName, EntityBuilder referenceBuilder, String[] fieldProperty, String fieldDescription) {
102            assert (elementDefinition == null) : ("The definition of element " + elementName + " is already built, cannot add field definition to it.");
103    
104            FieldDefinition fieldDefinition = new FieldDefinition(fieldName, fieldDefinitionList.size(), referenceBuilder.elementType, fieldDescription);
105            if (fieldProperty != null) {
106                for (int i = 0; i < fieldProperty.length; i++) {
107                    fieldDefinition.addProperty(fieldProperty[i]);
108                }
109            }
110            fieldDefinitionList.add(fieldDefinition);
111    
112            return fieldDefinition;
113        }
114    
115        /**
116         * Builds the element definition.
117         *
118         * @return  the element definition
119         */
120        protected EntityDefinition buildEntityDefinition() {
121            assert (elementDefinition == null) : ("The definition of element " + elementName + " is already built.");
122    
123            FieldDefinition[] fieldDefinition = new FieldDefinition[fieldDefinitionList.size()];
124            for (int i = 0; i < fieldDefinition.length; i++) {
125                fieldDefinition[i] = (FieldDefinition)(fieldDefinitionList.get(i));
126            }
127    
128            elementDefinition = new EntityDefinition(elementName, elementType, fieldDefinition, elementDescription);
129    
130            return (EntityDefinition)(elementDefinition);
131        }
132    
133        /**
134         * Builds the element definition.
135         *
136         * @return  the element definition
137         */
138        protected EventDefinition buildEventDefinition() {
139            assert (elementDefinition == null) : ("The definition of element " + elementName + " is already built.");
140    
141            FieldDefinition[] fieldDefinition = new FieldDefinition[fieldDefinitionList.size()];
142            for (int i = 0; i < fieldDefinition.length; i++) {
143                fieldDefinition[i] = (FieldDefinition)(fieldDefinitionList.get(i));
144            }
145    
146            elementDefinition = new EventDefinition(elementName, elementType, fieldDefinition, elementDescription);
147    
148            return (EventDefinition)(elementDefinition);
149        }
150    
151        /**
152         * Checks if definition is built.
153         *
154         * @return  true if definition is built
155         */
156        private boolean checkNewElement() {
157            for (int i = 0; i < field.length; i++) {
158                field[i] = Integer.MIN_VALUE;
159            }
160            return (elementDefinition != null);
161        }
162    
163        /**
164         * Starts building new entity.
165         *
166         * @param   entityName name of the entity
167         */
168        protected void newEntity(String entityName) {
169            field = new int[elementDefinition.getFieldDefinition().length];
170    
171            assert (checkNewElement()) : ("The definition of " + elementName + " must be built before building elements.");
172    
173            this.entityName = entityName;
174        }
175    
176        /**
177         * Starts building new event.
178         */
179        protected void newEvent() {
180            field = new int[elementDefinition.getFieldDefinition().length];
181    
182            assert (checkNewElement()) : ("The definition of " + elementName + " must be built before building elements.");
183        }
184    
185        /**
186         * Adds a value field.
187         *
188         * @param   key key of the field
189         * @param   value value of the field
190         */
191        public void addValueField(FieldDefinition fieldKey, int value) {
192            assert (elementDefinition != null) : ("The definition of " + elementName + " must be built before building elements.");
193            assert (elementDefinition.getFieldDefinition()[fieldKey.getIndex()].getReference() == -1) : ("Wrong field type, " + fieldKey.getName() + " should be a reference.");
194            assert (field[fieldKey.getIndex()] == Integer.MIN_VALUE) : (fieldKey.getName() + "is already added.");
195    
196            field[fieldKey.getIndex()] = value;
197        }
198    
199        /**
200         * Adds a reference field.
201         *
202         * @param   key key of the field
203         * @param   reference the reference
204         */
205        public void addReferenceField(FieldDefinition fieldKey, Entity reference) {
206            assert (elementDefinition != null) : ("The definition of " + elementName + " must be built before building elements.");
207            assert (elementDefinition.getFieldDefinition()[fieldKey.getIndex()].getReference() != -1) : ("Wrong field type, " + fieldKey.getName() + " should be a value.");
208            assert (elementDefinition.getFieldDefinition()[fieldKey.getIndex()].getReference() == reference.getType()) : ("Wrong entity type.");
209            assert (field[fieldKey.getIndex()] == Integer.MIN_VALUE) : (fieldKey.getName() + "is already added.");
210    
211            //try {
212            field[fieldKey.getIndex()] = reference.getId();
213            /*} catch (Exception e) {
214                int i=0;
215                i++;
216            } */
217        }
218    
219        /**
220         * Checks if all fields are added.
221         *
222         * @return  true if all fields are added
223         */
224        private boolean checkBuildElement() {
225            boolean returnVal = true;
226            for (int i = 0; i < field.length -1; i++) {
227                if (field[i] == Integer.MIN_VALUE) {
228                    returnVal = false;
229                    break;
230                }
231            }
232            return returnVal;
233        }
234    
235        /**
236         * Builds the entity.
237         *
238         * @return  the entity
239         */
240        protected Entity buildEntity() {
241            assert (elementDefinition != null) : ("The definition of " + elementName + " must be built before building elements.");
242            assert (checkBuildElement()) : ("Wrong field number.");
243    
244            entityCounter++;
245            return new Entity(elementDefinition.getType(), entityCounter, entityName, field);
246        }
247    
248        /**
249         * Builds the event.
250         *
251         * @return  the event
252         */
253        protected Event buildEvent() {
254            assert (elementDefinition != null) : ("The definition of " + elementName + " must be built before building elements.");
255            assert (checkBuildElement()) : ("Wrong field number.");
256    
257            return new Event(elementDefinition.getType(), field);
258        }
259    
260    
261    }