KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > buchuki > ensmer > prevayler > AreaPrevayler


1 /*
2  * Copyright 2004 Dusty Phillips
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.buchuki.ensmer.prevayler;
17
18 import java.io.Serializable JavaDoc;
19 import java.util.*;
20
21 import javax.media.j3d.Transform3D;
22 import javax.vecmath.Matrix4f;
23
24 import com.buchuki.annotations.*;
25
26 /**
27  * This class is responsible for managing prevayled objects related to the
28  * AreaManager.
29  *
30  * @author Dusty Phillips [dusty@buchuki.com]
31  */

32 @Optimize("previousList grows without bound")
33 public class AreaPrevayler implements Serializable JavaDoc {
34
35     /**
36      * Give it a serialversionUID so that later instances can reinstantiate it.
37      */

38     static final long serialVersionUID = 20050328L;
39
40     /**
41      * Retrieve the next available number to use as an Area Identifier. This
42      * method could cause problems if accessed by two running threads. However,
43      * because Prevayler serializes transactions, it does not need to be
44      * synchronized.
45      *
46      * @return the next available area identifier
47      */

48     public long nextAreaIdentifier() {
49         return ++lastAreaIdentifier;
50     }
51
52     /**
53      * Add an Area identifier to the list of currently available areas
54      *
55      * @param areaID the identifier for a new area to be added
56      */

57     public void addArea(Long JavaDoc areaID) {
58         areaMap.put(areaID, new PrevayledArea());
59     }
60
61     /**
62      * Remove an Area identifier from the list of currently available areas
63      *
64      * @param areaID the identifier for an area to be removed
65      */

66     public void removeArea(Long JavaDoc areaID) {
67         areaMap.remove(areaID);
68         //remove all instances from history
69
while (previousAreas.contains(areaID)) {
70             previousAreas.remove(areaID);
71         }
72         while (nextAreas.contains(areaID)) {
73             nextAreas.remove(areaID);
74         }
75
76     }
77
78     /**
79      * Obtain a list of identifiers for currently active areas. return array of
80      * enabled area identifiers
81      *
82      * @return The areas value
83      */

84     public long[] getAreas() {
85         Set areaList = areaMap.keySet();
86         long areas[] = new long[areaList.size()];
87         Iterator it = areaList.iterator();
88         int count = 0;
89         while (it.hasNext()) {
90             areas[count] = (Long JavaDoc) it.next();
91             count++;
92         }
93         return areas;
94     }
95
96     /**
97      * Return the previous area, or null if no previous area is available,
98      * while simultaneously updating the history and current Area
99      */

100     public Long JavaDoc previousArea() {
101         if (previousAreas.isEmpty()) {
102             return null;
103         }
104         nextAreas.addFirst(currentArea);
105         currentArea = previousAreas.removeFirst();
106         return currentArea;
107     }
108     
109     /**
110      * Return the next area, or null if no next area is available,
111      * while simultaneously updating the history and current area
112      */

113     public Long JavaDoc nextArea() {
114         if (nextAreas.isEmpty()) {
115             return null;
116         }
117         previousAreas.addFirst(currentArea);
118         currentArea = nextAreas.removeFirst();
119         return currentArea;
120     }
121     
122     /**
123      * Get an Area identifier from the history. The parameter tells you how
124      * many areas to go back in the history. 0 returns the identifier of
125      * the curent area, 1 returns the identifier of the previous area,
126      * 2 returns the identifier of the area accessed before that, etc. Further,
127      * -1 returns the identifier of the next area, -2 returns the identifier
128      * of the area accessed after that, etc. This may seem unintuitive, but
129      * because there are generally more previous areas and they are generally
130      * accessed more often, it makes sense to make their accessors positive.
131      * Think that history gets bigger if you go back in time.
132
133      * @param index the index in the history to retrieve an Area identifier for.
134      * 0 returns the current area, positive numbers return a previous area,
135      * negative numbers return a next area.
136      * @return a Long area identifier indicating the area at that position in
137      * the history. If the index is outside the Area's history, then null
138      * is returned.
139      */

140     public Long JavaDoc getHistoricalAreaID(int index) {
141         if (index == 0) {
142             return currentArea;
143         }
144         else if (index > 0) {
145             if (previousAreas.size() < index) {
146                 return null;
147             }
148             return previousAreas.get(index - 1);
149         }
150         else {
151             int trueIndex = index * -1;
152             if (nextAreas.size() < trueIndex) {
153                 return null;
154             }
155             return nextAreas.get(trueIndex - 1);
156         }
157         
158     }
159
160     /**
161      * Get the user position for a particular Area. If no Area is associated with
162      * that identifier, then null is returned. If no position is associated with
163      * that identifier, then position at the origin is returned
164      *
165      * @param id the identifier of the Area to retrieve the new position for
166      * @return the position for the given area, or null if no area is assoiated
167      * with that id, or the position at the origin if no position is
168      * associated
169      */

170     public Matrix4f getUserPosition(long id) {
171         PrevayledArea area = areaMap.get(id);
172         if (area == null) {
173             return null;
174         }
175         else if (area.getUserPosition() == null) {
176             Transform3D transform = new Transform3D();
177             Matrix4f matrix = new Matrix4f();
178             transform.get(matrix);
179             return matrix;
180         }
181         else {
182             return area.getUserPosition();
183         }
184     }
185
186     /**
187      * Retrieve the currently selected Area's identifier
188      *
189      * @return The currentArea value
190      */

191     public Long JavaDoc getCurrentArea() {
192         return currentArea;
193     }
194
195     /**
196      * Set the user position for a particular Area. If no Area is associated with
197      * that identifier, then no action is taken.
198      *
199      * @param id the identifier of the Area to set the new position for
200      * @param position a Matrix4f describing the user's orientation and location
201      * in this area
202      */

203     public void setUserPosition(Long JavaDoc id, Matrix4f position) {
204         PrevayledArea area = areaMap.get(id);
205         if (area != null) {
206             area.setUserPosition(position);
207         }
208     }
209
210     /**
211      * Set the given number as the currently selected Area. Manages the
212      * prevayled history
213      *
214      * @param areaID the id of the new current area
215      */

216     public void setCurrentArea(Long JavaDoc areaID) {
217         if (currentArea != null) {
218             previousAreas.addFirst(currentArea);
219         }
220         if (!nextAreas.isEmpty()) {
221             nextAreas.clear();
222         }
223         currentArea = areaID;
224     }
225     
226     /**
227      * Set whether or not the give areaID is readOnly or not
228      *
229      * @param areaID the area to set a readOnly attribute on
230      * @param readOnly true if the area cannot have objects added, false if
231      * it can
232      */

233     public void setReadOnly(Long JavaDoc areaID, boolean readOnly) {
234         PrevayledArea area = areaMap.get(areaID);
235         if (area != null) {
236             area.setReadOnly(readOnly);
237         }
238     }
239     
240     /**
241      * Determine whether the given area is read only or not
242      * @param areaID the identifier of teh area to get the readOnly attribute
243      * from
244      * @return false if the area exists and can have objects added to it,
245      * true if it cannot have objects added to it, or doesn't exist
246      */

247     public boolean isReadOnly(Long JavaDoc areaID) {
248         PrevayledArea area = areaMap.get(areaID);
249         if (area != null) {
250             return area.isReadOnly();
251         }
252         return true;
253     }
254
255     /**
256      * The last number given as an identifier for a newly generated Area.
257      */

258     private long lastAreaIdentifier;
259
260     /**
261      * Map of Longs representing areas that are permitted to be active to a <code>PrevayledArea</code>
262      * object containing information associated with that Area. Any long not in
263      * this list is an identifier for a nonexistent area and the identifier could
264      * potentially be reused. Unenforced (as yet) business logic says that an
265      * object cannot exist if its area does not exist
266      */

267     private Map<Long JavaDoc, PrevayledArea> areaMap = new HashMap<Long JavaDoc, PrevayledArea>();
268
269     /**
270      * The identifier of the area that is currently displayed.
271      */

272     private Long JavaDoc currentArea;
273     
274         
275     /**
276      * Stack containing Long area identifiers for previously selected areas.
277      */

278     private LinkedList<Long JavaDoc> previousAreas = new LinkedList<Long JavaDoc>();
279     
280     /**
281      * Stack containing Long area identifiers for next selected areas. This
282      * stack is reset every time the current area is set, and only contains
283      * values if the 'previousArea' method is called
284      */

285     private LinkedList<Long JavaDoc> nextAreas = new LinkedList<Long JavaDoc>();
286
287 }
288
289
Popular Tags