Merge lp:~mugle-dev/mugle/ui into lp:mugle

Proposed by Matt Giuca
Status: Merged
Merged at revision: 102
Proposed branch: lp:~mugle-dev/mugle/ui
Merge into: lp:mugle
Prerequisite: lp:~mugle-dev/mugle/dev-api
Diff against target: 2425 lines (+1111/-329)
46 files modified
src/au/edu/unimelb/csse/mugle/client/ClientService.java (+4/-2)
src/au/edu/unimelb/csse/mugle/client/ClientServiceAsync.java (+1/-1)
src/au/edu/unimelb/csse/mugle/client/Mugle.java (+68/-76)
src/au/edu/unimelb/csse/mugle/client/platform/AdminService.java (+2/-0)
src/au/edu/unimelb/csse/mugle/client/platform/AdminServiceAsync.java (+2/-0)
src/au/edu/unimelb/csse/mugle/client/platform/DeveloperService.java (+3/-1)
src/au/edu/unimelb/csse/mugle/client/platform/DeveloperServiceAsync.java (+2/-0)
src/au/edu/unimelb/csse/mugle/client/platform/GuestService.java (+7/-2)
src/au/edu/unimelb/csse/mugle/client/platform/GuestServiceAsync.java (+5/-2)
src/au/edu/unimelb/csse/mugle/client/ui/MugleDialogBox.java (+104/-0)
src/au/edu/unimelb/csse/mugle/client/ui/MugleUiBuilder.java (+192/-0)
src/au/edu/unimelb/csse/mugle/server/ClientServiceImpl.java (+2/-3)
src/au/edu/unimelb/csse/mugle/server/DataTestServiceImpl.java (+11/-2)
src/au/edu/unimelb/csse/mugle/server/GameFileServer.java (+94/-0)
src/au/edu/unimelb/csse/mugle/server/api/BadgeServiceImpl.java (+0/-2)
src/au/edu/unimelb/csse/mugle/server/api/HighscoreServiceImpl.java (+1/-9)
src/au/edu/unimelb/csse/mugle/server/api/KeyValueServiceImpl.java (+1/-11)
src/au/edu/unimelb/csse/mugle/server/api/UserServiceImpl.java (+2/-18)
src/au/edu/unimelb/csse/mugle/server/model/AchievementGetter.java (+6/-3)
src/au/edu/unimelb/csse/mugle/server/model/DevTeamGetter.java (+6/-4)
src/au/edu/unimelb/csse/mugle/server/model/GameFileData.java (+6/-31)
src/au/edu/unimelb/csse/mugle/server/model/GameFileGetter.java (+116/-0)
src/au/edu/unimelb/csse/mugle/server/model/GameVersionData.java (+7/-33)
src/au/edu/unimelb/csse/mugle/server/model/GameVersionGetter.java (+107/-0)
src/au/edu/unimelb/csse/mugle/server/model/KeyValuePairGetter.java (+13/-9)
src/au/edu/unimelb/csse/mugle/server/model/ModelDataClass.java (+12/-0)
src/au/edu/unimelb/csse/mugle/server/model/ModelWrapper.java (+55/-6)
src/au/edu/unimelb/csse/mugle/server/model/UserAchievementGetter.java (+12/-6)
src/au/edu/unimelb/csse/mugle/server/model/UserGameProfileGetter.java (+13/-7)
src/au/edu/unimelb/csse/mugle/server/model/UserGetter.java (+36/-14)
src/au/edu/unimelb/csse/mugle/server/model/annotations/UserLevel.java (+2/-2)
src/au/edu/unimelb/csse/mugle/server/platform/DeveloperServiceImpl.java (+1/-1)
src/au/edu/unimelb/csse/mugle/server/platform/GuestServiceImpl.java (+14/-2)
src/au/edu/unimelb/csse/mugle/shared/model/DataServiceAsync.java (+1/-1)
src/au/edu/unimelb/csse/mugle/shared/model/GameFile.java (+6/-14)
src/au/edu/unimelb/csse/mugle/shared/model/GameVersion.java (+3/-3)
src/au/edu/unimelb/csse/mugle/shared/model/ModelClass.java (+7/-4)
src/au/edu/unimelb/csse/mugle/shared/model/Role.java (+1/-1)
src/au/edu/unimelb/csse/mugle/shared/model/annotations/MugleDataWrapper.java (+6/-6)
src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/GameFileNotExists.java (+22/-0)
src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/GameNotExists.java (+4/-0)
src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/ServerException.java (+34/-0)
war/Mugle.css (+77/-22)
war/Mugle.html (+32/-23)
war/MugleIE6.css (+3/-0)
war/WEB-INF/web.xml (+8/-8)
To merge this branch: bzr merge lp:~mugle-dev/mugle/ui
Reviewer Review Type Date Requested Status
Matt Giuca Approve
Review via email: mp+59455@code.launchpad.net

Description of the change

Adds some new UI capabilities. Merge because it's too hard to separate changes between branches and trunk isn't being worked on anyway.

To post a comment you must log in.
Revision history for this message
Matt Giuca (mgiuca) wrote :

Let's just do it.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== renamed file 'src/au/edu/unimelb/csse/mugle/client/LoginService.java' => 'src/au/edu/unimelb/csse/mugle/client/ClientService.java'
2--- src/au/edu/unimelb/csse/mugle/client/LoginService.java 2011-03-06 10:21:39 +0000
3+++ src/au/edu/unimelb/csse/mugle/client/ClientService.java 2011-04-29 07:02:27 +0000
4@@ -16,10 +16,12 @@
5 */
6 package au.edu.unimelb.csse.mugle.client;
7
8+import au.edu.unimelb.csse.mugle.client.LoginInfo;
9+
10 import com.google.gwt.user.client.rpc.RemoteService;
11 import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
12
13-@RemoteServiceRelativePath("login")
14-public interface LoginService extends RemoteService {
15+@RemoteServiceRelativePath("client")
16+public interface ClientService extends RemoteService {
17 LoginInfo login(String requestUri);
18 }
19
20=== renamed file 'src/au/edu/unimelb/csse/mugle/client/LoginServiceAsync.java' => 'src/au/edu/unimelb/csse/mugle/client/ClientServiceAsync.java'
21--- src/au/edu/unimelb/csse/mugle/client/LoginServiceAsync.java 2011-03-06 10:21:39 +0000
22+++ src/au/edu/unimelb/csse/mugle/client/ClientServiceAsync.java 2011-04-29 07:02:27 +0000
23@@ -18,6 +18,6 @@
24
25 import com.google.gwt.user.client.rpc.AsyncCallback;
26
27-public interface LoginServiceAsync {
28+public interface ClientServiceAsync {
29 void login(String requestUri, AsyncCallback<LoginInfo> async);
30 }
31
32=== modified file 'src/au/edu/unimelb/csse/mugle/client/Mugle.java'
33--- src/au/edu/unimelb/csse/mugle/client/Mugle.java 2011-04-08 11:51:46 +0000
34+++ src/au/edu/unimelb/csse/mugle/client/Mugle.java 2011-04-29 07:02:27 +0000
35@@ -1,20 +1,17 @@
36 package au.edu.unimelb.csse.mugle.client;
37
38+import au.edu.unimelb.csse.mugle.client.ui.MugleUiBuilder;
39+
40 import com.google.gwt.core.client.EntryPoint;
41 import com.google.gwt.core.client.GWT;
42-import com.google.gwt.event.logical.shared.ResizeEvent;
43-import com.google.gwt.event.logical.shared.ResizeHandler;
44+import com.google.gwt.user.client.Element;
45+import com.google.gwt.event.dom.client.ClickEvent;
46+import com.google.gwt.event.dom.client.ClickHandler;
47 import com.google.gwt.user.client.DOM;
48-import com.google.gwt.user.client.Window;
49 import com.google.gwt.user.client.rpc.AsyncCallback;
50+import com.google.gwt.user.client.ui.Button;
51 import com.google.gwt.user.client.ui.Grid;
52-import com.google.gwt.user.client.ui.HTML;
53-import com.google.gwt.user.client.ui.HorizontalPanel;
54-import com.google.gwt.user.client.ui.Label;
55 import com.google.gwt.user.client.ui.RootPanel;
56-import com.google.gwt.user.client.ui.StackPanel;
57-import com.google.gwt.user.client.ui.VerticalPanel;
58-import com.google.gwt.user.client.ui.Widget;
59
60 /**
61 * Entry point classes define <code>onModuleLoad()</code>.
62@@ -27,13 +24,11 @@
63 private static final String SERVER_ERROR = "An error occurred while "
64 + "attempting to contact the server. Please check your network "
65 + "connection and try again.";
66-
67- private final DataTestServiceAsync dataTestService = GWT.create(DataTestService.class);
68-
69+
70 private RootPanel mainPanel = null;
71
72 private AuthenticatedUser authUser = new AuthenticatedUser();
73-
74+
75 /**
76 * This is the entry point method.
77 * Checks if logged in, if you are, runs the standard code for page,
78@@ -42,11 +37,13 @@
79 @Override
80 public void onModuleLoad() {
81
82- this.getStaticPanels();
83+ this.mainPanel = RootPanel.get("main-panel");
84+ Element element = RootPanel.get("error-display").getElement();
85+ DOM.removeChild(RootPanel.get("container").getElement(), element);
86
87 //Check login status using login service.
88- LoginServiceAsync loginService = GWT.create(LoginService.class);
89- loginService.login(GWT.getHostPageBaseURL(), new AsyncCallback<LoginInfo>() {
90+ ClientServiceAsync clientService = GWT.create(ClientService.class);
91+ clientService.login(GWT.getHostPageBaseURL(), new AsyncCallback<LoginInfo>() {
92
93 public void onFailure(Throwable error) {
94 System.err.print(error.getMessage());
95@@ -61,80 +58,75 @@
96 });
97
98 }
99-
100- private void getStaticPanels() {
101-
102- mainPanel = RootPanel.get("main-panel");
103-
104- /*
105- final RootPanel topPanel = RootPanel.get("user-panel");
106- final RootPanel footer = RootPanel.get("footer");
107- final RootPanel errPanel = RootPanel.get("error-display");
108-
109- Window.addResizeHandler(new ResizeHandler() {
110- public void onResize(ResizeEvent event) {
111- int h = topPanel.getOffsetHeight() + footer.getOffsetHeight() + errPanel.getOffsetHeight();
112- int height = event.getHeight() - h - 10;
113- if (height < 200) { height = 200; }
114- mainPanel.setHeight(height + "px");
115- }
116- });
117-
118- */
119-
120- }
121-
122+
123 private void arrangeUI() {
124
125 if (this.authUser.isLoggedIn()) {
126
127 Grid userPanel = new Grid(1,3);
128- RootPanel.get("user-panel-holder").add(userPanel);
129-
130- RootPanel mainPanel = RootPanel.get("main-panel");
131-
132- this.arrangeUserPanel(userPanel);
133- this.arrangeMainPanel(mainPanel);
134+ DOM.getElementById("user-panel-holder").appendChild(userPanel.getElement());
135+
136+ //this.mainPanel = RootPanel.get("main-panel");
137+
138+ MugleUiBuilder.arrangeUserPanel(userPanel, this.authUser);
139+ MugleUiBuilder.arrangeMainPanel(this.mainPanel);
140
141 } else {
142
143 this.mainPanel.add(this.authUser.resetLoginPanel());
144
145+
146+ // debugging
147+
148+ //final MugleDialogBox dialog = new MugleDialogBox("Data Population");
149+ final Button b = new Button("Populate Data");
150+
151+ //dialog.setReturnFocus(b);
152+
153+ b.addStyleName("sendButton");
154+ b.addClickHandler(new ClickHandler() {
155+
156+ DataTestServiceAsync dataTestService = GWT.create(DataTestService.class);
157+
158+ @Override
159+ public void onClick(ClickEvent event) {
160+
161+ dataTestService.populateDatastore(new AsyncCallback<String>() {
162+
163+ @Override
164+ public void onFailure(Throwable caught) {
165+ System.err.println("failed");
166+ b.setEnabled(true);
167+ b.setText("Try again! Populate Database");
168+ //dialog.setBody(new HTML(SERVER_ERROR));
169+ //dialog.center();
170+ //dialog.show();
171+ }
172+
173+ @Override
174+ public void onSuccess(String result) {
175+ System.err.println("success");
176+ b.setText("Database successfully populated");
177+ //dialog.setBody(new HTML(result));
178+ //dialog.show();
179+ //dialog.center();
180+ }
181+
182+ });
183+
184+ b.setEnabled(false);
185+ b.setText("Processing");
186+
187+ }
188+
189+ });
190+
191+ this.mainPanel.add(b);
192+
193 }
194
195 }
196
197- private void arrangeUserPanel(Grid userPanel) {
198-
199- RootPanel.get("user-panel-title").add(new HTML("<b>MUGLE</b>"));
200- userPanel.setWidget(0, 0, new HTML("<b>" + this.authUser.getLoginInfo().getEmailAddress() + "</b>"));
201- userPanel.setWidget(0, 1, new HTML("|"));
202- userPanel.setWidget(0, 2, this.authUser.getSignOutLink());
203-
204- }
205-
206- private void arrangeMainPanel(RootPanel mainPanel) {
207-
208- HorizontalPanel hp = new HorizontalPanel();
209-
210- // left panel
211- StackPanel sp = new StackPanel();
212- //sp.setWidth("200px");
213- DOM.setElementAttribute(sp.getElement(), "id", "tools-panel");
214-
215-
216- sp.setStackText(0, "Topic", false);
217-
218- sp.insert(new HTML("test"), 0);
219- sp.insert(new HTML("test 2"), 1);
220- sp.insert(new HTML("test 3"), 2);
221-
222- hp.insert(sp, 0);
223- hp.setHorizontalAlignment(HorizontalPanel.ALIGN_LEFT);
224- mainPanel.add(hp);
225-
226- }
227-
228 /*
229 private void loadDataTest() {
230 //Set up sign out hyperlink.
231
232=== modified file 'src/au/edu/unimelb/csse/mugle/client/platform/AdminService.java'
233--- src/au/edu/unimelb/csse/mugle/client/platform/AdminService.java 2011-03-20 11:06:48 +0000
234+++ src/au/edu/unimelb/csse/mugle/client/platform/AdminService.java 2011-04-29 07:02:27 +0000
235@@ -41,6 +41,8 @@
236
237 boolean banUser(Long id) throws UserNotExists, UserPrivilegeException;
238
239+ User getCurrentUserDetails() throws ServerException;
240+
241 // DevTeams
242
243 DevTeam addNewDevTeam(DevTeam devTeam) throws DevTeamExists, UserPrivilegeException;
244
245=== modified file 'src/au/edu/unimelb/csse/mugle/client/platform/AdminServiceAsync.java'
246--- src/au/edu/unimelb/csse/mugle/client/platform/AdminServiceAsync.java 2011-03-20 11:06:48 +0000
247+++ src/au/edu/unimelb/csse/mugle/client/platform/AdminServiceAsync.java 2011-04-29 07:02:27 +0000
248@@ -100,5 +100,7 @@
249
250 void demoteGame(String promotedGameKey,
251 AsyncCallback<GameVersion> callback);
252+
253+ void getCurrentUserDetails(AsyncCallback<User> callback);
254
255 }
256
257=== modified file 'src/au/edu/unimelb/csse/mugle/client/platform/DeveloperService.java'
258--- src/au/edu/unimelb/csse/mugle/client/platform/DeveloperService.java 2011-03-20 11:06:48 +0000
259+++ src/au/edu/unimelb/csse/mugle/client/platform/DeveloperService.java 2011-04-29 07:02:27 +0000
260@@ -21,12 +21,13 @@
261 import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameNotExists;
262 import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameVersionExists;
263 import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameVersionNotExists;
264+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.ServerException;
265 import au.edu.unimelb.csse.mugle.shared.platform.exceptions.UserPrivilegeException;
266
267 import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
268
269 @RemoteServiceRelativePath("dev")
270-public interface DeveloperService extends UserService {
271+public interface DeveloperService extends GuestService {
272
273 GameVersion addGameVersion(GameVersion gameVersion) throws GameVersionExists, GameNotExists, UserPrivilegeException;
274
275@@ -38,4 +39,5 @@
276
277 boolean removeGameVersion(Long pKey) throws GameVersionNotExists, UserPrivilegeException;
278
279+ User getCurrentUserDetails() throws ServerException;
280 }
281
282=== modified file 'src/au/edu/unimelb/csse/mugle/client/platform/DeveloperServiceAsync.java'
283--- src/au/edu/unimelb/csse/mugle/client/platform/DeveloperServiceAsync.java 2011-03-20 11:06:48 +0000
284+++ src/au/edu/unimelb/csse/mugle/client/platform/DeveloperServiceAsync.java 2011-04-29 07:02:27 +0000
285@@ -42,4 +42,6 @@
286
287 void removeGameVersion(Long pKey, AsyncCallback<Boolean> callback);
288
289+ void getCurrentUserDetails(AsyncCallback<User> callback);
290+
291 }
292
293=== renamed file 'src/au/edu/unimelb/csse/mugle/client/platform/UserService.java' => 'src/au/edu/unimelb/csse/mugle/client/platform/GuestService.java'
294--- src/au/edu/unimelb/csse/mugle/client/platform/UserService.java 2011-03-09 08:55:08 +0000
295+++ src/au/edu/unimelb/csse/mugle/client/platform/GuestService.java 2011-04-29 07:02:27 +0000
296@@ -17,10 +17,15 @@
297
298 package au.edu.unimelb.csse.mugle.client.platform;
299
300+import au.edu.unimelb.csse.mugle.shared.model.User;
301+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.ServerException;
302+
303 import com.google.gwt.user.client.rpc.RemoteService;
304 import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
305
306-@RemoteServiceRelativePath("users")
307-public interface UserService extends RemoteService {
308+@RemoteServiceRelativePath("guests")
309+public interface GuestService extends RemoteService {
310
311+ User getCurrentUserDetails() throws ServerException;
312+
313 }
314
315=== renamed file 'src/au/edu/unimelb/csse/mugle/client/platform/UserServiceAsync.java' => 'src/au/edu/unimelb/csse/mugle/client/platform/GuestServiceAsync.java'
316--- src/au/edu/unimelb/csse/mugle/client/platform/UserServiceAsync.java 2011-03-10 04:50:07 +0000
317+++ src/au/edu/unimelb/csse/mugle/client/platform/GuestServiceAsync.java 2011-04-29 07:02:27 +0000
318@@ -19,10 +19,13 @@
319
320 import com.google.gwt.user.client.rpc.AsyncCallback;
321
322+import au.edu.unimelb.csse.mugle.shared.model.User;
323+
324 /**
325- * The async counterpart of <code>UserService</code>.
326+ * The async counterpart of <code>GuestService</code>.
327 */
328-public interface UserServiceAsync {
329+public interface GuestServiceAsync {
330
331+ void getCurrentUserDetails(AsyncCallback<User> callback);
332
333 }
334
335=== added file 'src/au/edu/unimelb/csse/mugle/client/ui/MugleDialogBox.java'
336--- src/au/edu/unimelb/csse/mugle/client/ui/MugleDialogBox.java 1970-01-01 00:00:00 +0000
337+++ src/au/edu/unimelb/csse/mugle/client/ui/MugleDialogBox.java 2011-04-29 07:02:27 +0000
338@@ -0,0 +1,104 @@
339+package au.edu.unimelb.csse.mugle.client.ui;
340+
341+import com.google.gwt.event.dom.client.ClickEvent;
342+import com.google.gwt.event.dom.client.ClickHandler;
343+import com.google.gwt.user.client.ui.Button;
344+import com.google.gwt.user.client.ui.DialogBox;
345+import com.google.gwt.user.client.ui.FocusWidget;
346+import com.google.gwt.user.client.ui.HTML;
347+import com.google.gwt.user.client.ui.HorizontalPanel;
348+import com.google.gwt.user.client.ui.VerticalPanel;
349+
350+public class MugleDialogBox extends DialogBox {
351+
352+ private final Button closeButton = new Button("Close");
353+ private final HorizontalPanel bodyHolder = new HorizontalPanel();
354+
355+ private FocusWidget returnFocus = null;
356+ private HTML body = new HTML();
357+
358+ public MugleDialogBox(String text, HTML body, FocusWidget focus) {
359+ super(false);
360+ this.returnFocus = focus;
361+ this.setText(text);
362+ this.setup();
363+ this.setBody(body);
364+ }
365+
366+ public MugleDialogBox(String text) {
367+ super(false);
368+ this.setText(text);
369+ this.setup();
370+ }
371+
372+ public MugleDialogBox() {
373+ super(false);
374+ this.setup();
375+ }
376+
377+ private void setup() {
378+
379+ this.setAnimationEnabled(true);
380+
381+ this.closeButton.getElement().setId("closeButton");
382+ VerticalPanel dialogVPanel = new VerticalPanel();
383+ dialogVPanel.addStyleName("dialogVPanel");
384+ dialogVPanel.add(bodyHolder);
385+ dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
386+ dialogVPanel.add(closeButton);
387+ this.setWidget(dialogVPanel);
388+
389+ // Add a handler to close the DialogBox
390+ closeButton.addClickHandler(new DialogClickHandler(this));
391+
392+ }
393+
394+ public void show() {
395+ this.center();
396+ this.closeButton.setFocus(true);
397+ }
398+
399+ protected Button getCloseButton() {
400+ return this.closeButton;
401+ }
402+
403+ protected FocusWidget getReturnFocus() {
404+ return this.returnFocus;
405+ }
406+
407+ public HTML getBody() {
408+ return this.body;
409+ }
410+
411+ public void setBody(HTML body) {
412+ this.body = body;
413+ if (body != null) {
414+ this.bodyHolder.clear();
415+ this.bodyHolder.add(body);
416+ }
417+ }
418+
419+ public void setReturnFocus(FocusWidget returnFocus) {
420+ this.returnFocus = returnFocus;
421+ }
422+
423+ private class DialogClickHandler implements ClickHandler {
424+
425+ MugleDialogBox mdb = null;
426+
427+ public DialogClickHandler(MugleDialogBox mdb) {
428+ this.mdb = mdb;
429+ }
430+
431+ @Override
432+ public void onClick(ClickEvent event) {
433+ this.mdb.hide();
434+ if (this.mdb.getReturnFocus() != null) {
435+ this.mdb.getReturnFocus().setEnabled(true);
436+ this.mdb.getReturnFocus().setFocus(true);
437+ }
438+ }
439+
440+ }
441+
442+}
443
444=== modified file 'src/au/edu/unimelb/csse/mugle/client/ui/MugleUiBuilder.java'
445--- src/au/edu/unimelb/csse/mugle/client/ui/MugleUiBuilder.java 2011-04-29 07:02:27 +0000
446+++ src/au/edu/unimelb/csse/mugle/client/ui/MugleUiBuilder.java 2011-04-29 07:02:27 +0000
447@@ -3,17 +3,38 @@
448 import java.util.Collection;
449 import java.util.Iterator;
450
451+import au.edu.unimelb.csse.mugle.client.AuthenticatedUser;
452+import au.edu.unimelb.csse.mugle.client.platform.GuestService;
453+import au.edu.unimelb.csse.mugle.client.platform.GuestServiceAsync;
454+import au.edu.unimelb.csse.mugle.shared.model.Role;
455+import au.edu.unimelb.csse.mugle.shared.model.User;
456+
457+import com.google.gwt.core.client.GWT;
458+import com.google.gwt.dom.client.Style;
459+import com.google.gwt.dom.client.Style.Overflow;
460+import com.google.gwt.dom.client.Style.Unit;
461 import com.google.gwt.event.dom.client.ClickHandler;
462+import com.google.gwt.user.client.DOM;
463+import com.google.gwt.user.client.rpc.AsyncCallback;
464+import com.google.gwt.user.client.ui.AbsolutePanel;
465+import com.google.gwt.user.client.ui.Anchor;
466 import com.google.gwt.user.client.ui.Button;
467 import com.google.gwt.user.client.ui.CellPanel;
468+import com.google.gwt.user.client.ui.DockLayoutPanel;
469 import com.google.gwt.user.client.ui.FlexTable;
470+import com.google.gwt.user.client.ui.Grid;
471+import com.google.gwt.user.client.ui.HTML;
472 import com.google.gwt.user.client.ui.HorizontalPanel;
473 import com.google.gwt.user.client.ui.Label;
474+import com.google.gwt.user.client.ui.RootPanel;
475+import com.google.gwt.user.client.ui.StackPanel;
476 import com.google.gwt.user.client.ui.VerticalPanel;
477 import com.google.gwt.user.client.ui.Widget;
478
479 public class MugleUiBuilder {
480
481+ private static GuestServiceAsync guestService = GWT.create(GuestService.class);
482+
483 private MugleUiBuilder() { }
484
485 public static CellPanel buildStringTable(Collection<Collection<String>> list, Collection<String> headers) {
486@@ -140,5 +161,176 @@
487 if (handler != null) { b.addClickHandler(handler); }
488 panel.add(b);
489 }
490+
491+ public static <T extends Widget> T setId(T w, String id) {
492+ w.getElement().setId(id);
493+ return w;
494+ }
495+
496+ public static void arrangeUserPanel(Grid userPanel, AuthenticatedUser authuser) {
497+
498+ DOM.getElementById("user-panel-title").appendChild((new HTML("<b>MUGLE</b>")).getElement());
499+ userPanel.setWidget(0, 0, new HTML("<b>" + authuser.getLoginInfo().getEmailAddress() + "</b>"));
500+ userPanel.setWidget(0, 1, new HTML("|"));
501+ userPanel.setWidget(0, 2, authuser.getSignOutLink());
502+
503+ }
504+
505+ public static void arrangeMainPanel(RootPanel mainPanel) {
506+
507+ AbsolutePanel container = setId(new AbsolutePanel(), "main-panel-container");
508+ mainPanel.add(container);
509+
510+ AbsolutePanel inner = setId(new AbsolutePanel(), "main-panel-container-inner");
511+ inner.getElement().getStyle().setOverflow(Overflow.VISIBLE);
512+ container.add(inner);
513+
514+ AbsolutePanel tp = setId(new AbsolutePanel(), "tools-panel");
515+ AbsolutePanel rp = setId(new AbsolutePanel(), "right-panel");
516+ AbsolutePanel rpi = setId(new AbsolutePanel(), "right-panel-inner");
517+
518+ tp.add(buildToolsPanel());
519+ rpi.add(buildRightPanel());
520+ rp.add(rpi);
521+
522+ inner.add(tp);
523+ inner.add(rp);
524+
525+ }
526+
527+ private static Widget buildToolsPanel() {
528+
529+ // left panel
530+ final StackPanel sp = new StackPanel();
531+ sp.setWidth("100%");
532+ sp.getElement().getStyle().setFontSize(1, Unit.EM);
533+
534+ System.out.println("test1");
535+
536+ guestService.getCurrentUserDetails(new AsyncCallback<User>() {
537+
538+ @Override
539+ public void onSuccess(User result) {
540+
541+ System.out.println("success");
542+
543+ Widget tmp = null;
544+ if ((tmp = buildMyMugle(result)) != null) {
545+ sp.add(tmp, "My Mugle", false);
546+ }
547+ if ((tmp = buildMuglePublic(result)) != null) {
548+ sp.add(tmp, "Mugle Public", false);
549+ }
550+ if ((tmp = buildSettings(result)) != null) {
551+ sp.add(tmp, "Settings", false);
552+ }
553+ if ((tmp = buildAdmin(result)) != null) {
554+ sp.add(tmp, "Admin", false);
555+ }
556+
557+ }
558+
559+ @Override
560+ public void onFailure(Throwable caught) {
561+
562+ // TODO Auto-generated method stub
563+ System.out.println("fail");
564+
565+ }
566+
567+ });
568+
569+ return sp;
570+
571+ }
572+
573+ private static Widget buildMyMugle(User user) {
574+
575+ Role role = user.getRole();
576+
577+ switch (role) {
578+
579+ case ADMIN:
580+ case DEVELOPER:
581+
582+ VerticalPanel vp = new VerticalPanel();
583+ vp.add(new Anchor("Promoted Games"));
584+ vp.add(new Anchor("Games Gallery"));
585+ vp.add(new Anchor("Promoted Games"));
586+ return vp;
587+
588+ }
589+
590+ return null;
591+
592+ }
593
594+ private static Widget buildMuglePublic(User user) {
595+
596+ VerticalPanel vp = new VerticalPanel();
597+
598+ vp.add(new Anchor("Promoted Games"));
599+ vp.add(new Anchor("Games Gallery"));
600+
601+ return vp;
602+
603+ }
604+
605+ private static Widget buildSettings(User user) {
606+
607+ VerticalPanel vp = new VerticalPanel();
608+
609+ vp.add(new Anchor("Settings 1"));
610+ vp.add(new Anchor("Settings 2"));
611+
612+ return vp;
613+
614+ }
615+
616+ private static Widget buildAdmin(User user) {
617+
618+ Role role = user.getRole();
619+
620+ switch (role) {
621+
622+ case ADMIN:
623+
624+ VerticalPanel vp = new VerticalPanel();
625+ vp.add(new Anchor("Promoted Games"));
626+ vp.add(new Anchor("Games Gallery"));
627+ vp.add(new Anchor("Promoted Games"));
628+ return vp;
629+
630+ }
631+
632+ return null;
633+
634+ }
635+
636+ private static Widget buildRightPanel() {
637+
638+ final HorizontalPanel panel = new HorizontalPanel();
639+
640+ panel.add(new HTML("Under Construction!"));
641+
642+ // debug
643+ GuestServiceAsync us = GWT.create(GuestService.class);
644+ us.getCurrentUserDetails(new AsyncCallback<User>() {
645+
646+ @Override
647+ public void onSuccess(User result) {
648+ panel.add(new HTML("NAME: "+result.getFullName()));
649+ }
650+
651+ @Override
652+ public void onFailure(Throwable caught) {
653+ panel.add(new HTML("FAILED!"));
654+ }
655+
656+ });
657+
658+ return panel;
659+
660+ }
661+
662 }
663
664=== renamed file 'src/au/edu/unimelb/csse/mugle/server/LoginServiceImpl.java' => 'src/au/edu/unimelb/csse/mugle/server/ClientServiceImpl.java'
665--- src/au/edu/unimelb/csse/mugle/server/LoginServiceImpl.java 2011-04-29 07:02:27 +0000
666+++ src/au/edu/unimelb/csse/mugle/server/ClientServiceImpl.java 2011-04-29 07:02:27 +0000
667@@ -20,12 +20,11 @@
668 import com.google.appengine.api.users.UserService;
669 import com.google.appengine.api.users.UserServiceFactory;
670 import au.edu.unimelb.csse.mugle.client.LoginInfo;
671-import au.edu.unimelb.csse.mugle.client.LoginService;
672+import au.edu.unimelb.csse.mugle.client.ClientService;
673 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
674
675 @SuppressWarnings("serial")
676-public class LoginServiceImpl extends RemoteServiceServlet implements
677- LoginService {
678+public class ClientServiceImpl extends RemoteServiceServlet implements ClientService {
679
680 public LoginInfo login(String requestUri) {
681 UserService userService = UserServiceFactory.getUserService();
682
683=== modified file 'src/au/edu/unimelb/csse/mugle/server/DataTestServiceImpl.java'
684--- src/au/edu/unimelb/csse/mugle/server/DataTestServiceImpl.java 2011-04-29 07:02:27 +0000
685+++ src/au/edu/unimelb/csse/mugle/server/DataTestServiceImpl.java 2011-04-29 07:02:27 +0000
686@@ -31,26 +31,35 @@
687
688 PersistenceManager pm = PMF.getManager();
689
690+ System.err.println("test1");
691+
692 if (pm == null) {
693 return "Datastore populating failed!";
694 }
695
696+ System.err.println("test2");
697+
698 UserData[] users = new UserData[] {
699 new UserData("~matt", "Matt Giuca", "matt@test.com", Role.ADMIN),
700 new UserData("~scott", "Scott Ritchie", "scott@test.com", Role.ADMIN),
701 new UserData("~prageeth", "Prageeth Silva", "prageeth@test.com", Role.ADMIN),
702 new UserData("~bob", "Bob", "bob@test.com", Role.DEVELOPER),
703 new UserData("~jim", "Jim", "jim@test.com", Role.DEVELOPER),
704- new UserData("~john", "John", "john@test.com", Role.USER),
705+ new UserData("~john", "John", "john@test.com", Role.GUEST),
706 new UserData("~admin", "Admin", "admin@test.com", Role.ADMIN),
707- new UserData("~dev", "Dev", "dev@test.com", Role.DEVELOPER)
708+ new UserData("~dev", "Dev", "dev@test.com", Role.DEVELOPER),
709+ new UserData("~test", "Test", "test@example.com", Role.DEVELOPER)
710 };
711
712+ System.err.println("test3");
713+
714 pm.makePersistentAll(users);
715 pm.makePersistent(users[0]);
716 pm.flush();
717 pm.close();
718
719+ System.err.println("test4");
720+
721 return "Data addition succeful!";
722
723 }
724
725=== added file 'src/au/edu/unimelb/csse/mugle/server/GameFileServer.java'
726--- src/au/edu/unimelb/csse/mugle/server/GameFileServer.java 1970-01-01 00:00:00 +0000
727+++ src/au/edu/unimelb/csse/mugle/server/GameFileServer.java 2011-04-29 07:02:27 +0000
728@@ -0,0 +1,94 @@
729+/* Melbourne University Game-based Learning Environment
730+ * Copyright (C) 2011 The University of Melbourne
731+ *
732+ * This program is free software: you can redistribute it and/or modify
733+ * it under the terms of the GNU General Public License as published by
734+ * the Free Software Foundation, either version 3 of the License, or
735+ * (at your option) any later version.
736+ *
737+ * This program is distributed in the hope that it will be useful,
738+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
739+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
740+ * GNU General Public License for more details.
741+ *
742+ * You should have received a copy of the GNU General Public License
743+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
744+ */
745+package au.edu.unimelb.csse.mugle.server;
746+
747+import java.io.IOException;
748+import java.util.Map;
749+import java.util.Map.Entry;
750+
751+import javax.servlet.ServletException;
752+import javax.servlet.http.HttpServlet;
753+import javax.servlet.http.HttpServletRequest;
754+import javax.servlet.http.HttpServletResponse;
755+
756+import au.edu.unimelb.csse.mugle.server.model.GameFileData;
757+import au.edu.unimelb.csse.mugle.server.model.GameFileGetter;
758+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameFileNotExists;
759+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameNotExists;
760+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameVersionNotExists;
761+
762+import com.google.appengine.api.blobstore.BlobKey;
763+import com.google.appengine.api.blobstore.BlobstoreService;
764+import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
765+
766+@SuppressWarnings("serial")
767+public class GameFileServer extends HttpServlet {
768+
769+ public void doGet(HttpServletRequest req, HttpServletResponse res)
770+ throws IOException {
771+ BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
772+
773+ try {
774+ BlobKey blobKey = getBlobKey(req);
775+ blobstoreService.serve(blobKey, res);
776+ } catch (GameFileNotExists e) {
777+ //TODO: Construct a page with the error
778+ }
779+ }
780+
781+ private BlobKey getBlobKey(HttpServletRequest req)
782+ throws GameFileNotExists {
783+ GameFileGetter gfg = new GameFileGetter();
784+ String gameName = null;
785+ String gameVersion = null;
786+ String path = null;
787+
788+ /* We need to parse the request to get the gameName, gameVersion
789+ * and path,
790+ * URLs are in the form /game/gameName/gameVersion/path
791+ */
792+ String toParse = req.getRequestURI().split("/game/")[1]; // gets everything after /game/ in the URI
793+ String[] splitted = toParse.split("/");
794+ gameName = splitted[0];
795+ gameVersion = splitted[1];
796+ path = toParse.split(gameVersion)[1];
797+
798+ try {
799+ GameFileData file = gfg.getGameFile(gameName, gameVersion, path);
800+ return file.getBlobKey();
801+ } catch (GameNotExists e) {
802+ throw new GameFileNotExists(gameName, gameVersion, path);
803+ } catch (GameVersionNotExists e) {
804+ throw new GameFileNotExists(gameName, gameVersion, path);
805+ }
806+ }
807+
808+ /*
809+ public void doPost(HttpServletRequest req, HttpServletResponse res)
810+ throws ServletException, IOException{
811+ BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
812+
813+ Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
814+ /* We want to iterate over each of the blobs, and create the
815+ * appropriate datastore classes
816+ *
817+ for(Entry<String, BlobKey> blobEntry : blobs.entrySet()){
818+
819+ }
820+
821+ } */
822+}
823
824=== modified file 'src/au/edu/unimelb/csse/mugle/server/api/BadgeServiceImpl.java'
825--- src/au/edu/unimelb/csse/mugle/server/api/BadgeServiceImpl.java 2011-04-29 07:02:27 +0000
826+++ src/au/edu/unimelb/csse/mugle/server/api/BadgeServiceImpl.java 2011-04-29 07:02:27 +0000
827@@ -58,8 +58,6 @@
828 UserAchievementGetter u = new UserAchievementGetter();
829 try {
830 return u.getUserAchievement(pm, name, gameToken);
831- } catch (UserNotExists e) {
832- throw new Error(e);
833 } catch (AchievementNotExists e) {
834 throw new BadgeError(e.getMessage());
835 }
836
837=== modified file 'src/au/edu/unimelb/csse/mugle/server/api/HighscoreServiceImpl.java'
838--- src/au/edu/unimelb/csse/mugle/server/api/HighscoreServiceImpl.java 2011-04-29 07:02:27 +0000
839+++ src/au/edu/unimelb/csse/mugle/server/api/HighscoreServiceImpl.java 2011-04-29 07:02:27 +0000
840@@ -22,8 +22,6 @@
841 import au.edu.unimelb.csse.mugle.server.model.UserGameProfileGetter;
842 import au.edu.unimelb.csse.mugle.shared.api.GameTokenError;
843 import au.edu.unimelb.csse.mugle.server.model.UserGameProfileData;
844-import au.edu.unimelb.csse.mugle.shared.platform.exceptions.UserNotExists;
845-
846 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
847
848 import javax.jdo.PersistenceManager;
849@@ -40,11 +38,7 @@
850 public int getHighScore(String gameToken) throws GameTokenError {
851 UserGameProfileGetter u = new UserGameProfileGetter();
852 UserGameProfileData ugp;
853- try {
854- ugp = u.getCurrentUserGameProfile(gameToken);
855- } catch (UserNotExists e) {
856- throw new Error(e);
857- }
858+ ugp = u.getCurrentUserGameProfile(gameToken);
859 return ugp.getHighscore();
860 }
861
862@@ -56,8 +50,6 @@
863 ugp = u.getCurrentUserGameProfile(pm, gameToken);
864 if (score > ugp.getHighscore())
865 ugp.setHighscore(score);
866- } catch (UserNotExists e) {
867- throw new Error(e);
868 } finally {
869 pm.close();
870 }
871
872=== modified file 'src/au/edu/unimelb/csse/mugle/server/api/KeyValueServiceImpl.java'
873--- src/au/edu/unimelb/csse/mugle/server/api/KeyValueServiceImpl.java 2011-04-29 07:02:27 +0000
874+++ src/au/edu/unimelb/csse/mugle/server/api/KeyValueServiceImpl.java 2011-04-29 07:02:27 +0000
875@@ -25,8 +25,6 @@
876 import au.edu.unimelb.csse.mugle.shared.api.GameTokenError;
877 import au.edu.unimelb.csse.mugle.shared.api.KeyError;
878 import au.edu.unimelb.csse.mugle.server.model.KeyValuePairData;
879-import au.edu.unimelb.csse.mugle.shared.platform.exceptions.*;
880-
881 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
882
883 import javax.jdo.PersistenceManager;
884@@ -48,8 +46,6 @@
885 try {
886 kvp = k.getKeyValuePair(pm, key, gameToken, true);
887 kvp.setValue(value);
888- } catch (UserNotExists e) {
889- throw new Error(e);
890 } catch (KeyError e) {
891 // XXX This should never happen (since we are using createIfNotFound=true)
892 throw new Error(e);
893@@ -63,11 +59,7 @@
894 {
895 KeyValuePairGetter k = new KeyValuePairGetter();
896 KeyValuePairData kvp;
897- try {
898- kvp = k.getKeyValuePair(key, gameToken);
899- } catch (UserNotExists e) {
900- throw new Error(e);
901- }
902+ kvp = k.getKeyValuePair(key, gameToken);
903 return (Serializable) kvp.getValue();
904 }
905
906@@ -77,8 +69,6 @@
907 KeyValuePairGetter k = new KeyValuePairGetter();
908 try {
909 k.getKeyValuePair(key, gameToken);
910- } catch (UserNotExists e) {
911- throw new Error(e);
912 } catch (KeyError e) {
913 return false;
914 }
915
916=== modified file 'src/au/edu/unimelb/csse/mugle/server/api/UserServiceImpl.java'
917--- src/au/edu/unimelb/csse/mugle/server/api/UserServiceImpl.java 2011-04-29 07:02:27 +0000
918+++ src/au/edu/unimelb/csse/mugle/server/api/UserServiceImpl.java 2011-04-29 07:02:27 +0000
919@@ -19,8 +19,6 @@
920
921 import au.edu.unimelb.csse.mugle.client.api.UserService;
922 import au.edu.unimelb.csse.mugle.server.model.UserGetter;
923-import au.edu.unimelb.csse.mugle.shared.platform.exceptions.UserNotExists;
924-
925 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
926
927
928@@ -34,25 +32,11 @@
929
930 public String getUserNickName() {
931 UserGetter u = new UserGetter();
932- try
933- {
934- return u.getCurrentUser().getUrlName();
935- }
936- catch (UserNotExists e)
937- {
938- throw new Error(e);
939- }
940+ return u.getCurrentUser().getUrlName();
941 }
942
943 public String getUserID() {
944 UserGetter u = new UserGetter();
945- try
946- {
947- return u.getCurrentUser().getGoogleID();
948- }
949- catch (UserNotExists e)
950- {
951- throw new Error(e);
952- }
953+ return u.getCurrentUser().getGoogleID();
954 }
955 }
956
957=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/AchievementGetter.java'
958--- src/au/edu/unimelb/csse/mugle/server/model/AchievementGetter.java 2011-04-29 07:02:27 +0000
959+++ src/au/edu/unimelb/csse/mugle/server/model/AchievementGetter.java 2011-04-29 07:02:27 +0000
960@@ -17,6 +17,8 @@
961
962 package au.edu.unimelb.csse.mugle.server.model;
963
964+import java.util.List;
965+
966 import javax.jdo.PersistenceManager;
967 import javax.jdo.Query;
968
969@@ -54,6 +56,7 @@
970 * @throws GameTokenError
971 * @throws AchievementNotExists
972 */
973+ @SuppressWarnings("unchecked")
974 public AchievementData getAchievement(PersistenceManager pm, String name, String gameToken)
975 throws GameTokenError, AchievementNotExists {
976 GameGetter g = new GameGetter();
977@@ -61,13 +64,13 @@
978
979 Query q = pm.newQuery(AchievementData.class, "game == g && name == n");
980 q.declareParameters("GameData g, String n");
981- AchievementData achievement = (AchievementData) q.execute(curGame, name);
982+ List<AchievementData> results = (List<AchievementData>) q.execute(curGame, name);
983
984- if (achievement == null) {
985+ if (results.isEmpty()) {
986 throw new AchievementNotExists(curGame.getUrlName(), name);
987 }
988
989- return achievement;
990+ return results.get(0);
991 }
992
993 /**
994
995=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/DevTeamGetter.java'
996--- src/au/edu/unimelb/csse/mugle/server/model/DevTeamGetter.java 2011-04-29 07:02:27 +0000
997+++ src/au/edu/unimelb/csse/mugle/server/model/DevTeamGetter.java 2011-04-29 07:02:27 +0000
998@@ -1,5 +1,7 @@
999 package au.edu.unimelb.csse.mugle.server.model;
1000
1001+import java.util.List;
1002+
1003 import javax.jdo.PersistenceManager;
1004 import javax.jdo.Query;
1005
1006@@ -31,17 +33,17 @@
1007 * @return The DevTeamData
1008 * @throws DevTeamDataNotExists
1009 */
1010+ @SuppressWarnings("unchecked")
1011 public DevTeamData getDevTeam(PersistenceManager pm, String name) throws DevTeamNotExists {
1012- DevTeamData devTeam= null;
1013 Query q = pm.newQuery(DevTeamData.class, "urlName == u");
1014 q.declareParameters("String u");
1015- devTeam = (DevTeamData) q.execute(name);
1016+ List<DevTeamData> results = (List<DevTeamData>) q.execute(name);
1017
1018- if (devTeam == null) {
1019+ if (results.isEmpty()) {
1020 throw new DevTeamNotExists(name);
1021 }
1022
1023- return devTeam;
1024+ return results.get(0);
1025 }
1026 /**
1027 * Gets the DevTeamDataData by its primary key - READ ONLY
1028
1029=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/GameFileData.java'
1030--- src/au/edu/unimelb/csse/mugle/server/model/GameFileData.java 2011-04-29 07:02:27 +0000
1031+++ src/au/edu/unimelb/csse/mugle/server/model/GameFileData.java 2011-04-29 07:02:27 +0000
1032@@ -17,9 +17,6 @@
1033
1034 package au.edu.unimelb.csse.mugle.server.model;
1035
1036-import java.util.HashSet;
1037-import java.util.Set;
1038-
1039 import javax.jdo.annotations.IdGeneratorStrategy;
1040 import javax.jdo.annotations.PersistenceCapable;
1041 import javax.jdo.annotations.Persistent;
1042@@ -54,17 +51,16 @@
1043
1044 @UserLevel(privateView=Role.DEVELOPER, publicView=Role.DEVELOPER, useMethod=true, mappedBy="getBlobKeyString")
1045 @Persistent
1046- private BlobKey blobKey; //key to the actual blob
1047+ private BlobKey blobKey; //key to the actual blob -- may be shared between GameFiles across versions
1048
1049- // Many-to-many
1050- @UserLevel(privateView=Role.DEVELOPER, publicView=Role.DEVELOPER, useMethod=true, mappedBy="keysToGameVersions")
1051+ @UserLevel(privateView=Role.DEVELOPER, publicView=Role.DEVELOPER, mappedBy="version")
1052 @Persistent
1053- private Set<Key> versions; //Game versions this file belongs to
1054+ private GameVersionData version; //Game version this Gamefile belongs to
1055
1056
1057 // Constructors
1058 public GameFileData() {
1059- this.versions = new HashSet<Key>();
1060+ this.version = null;
1061 this.setMimeType(null);
1062 this.setBlobKey(null);
1063 this.path = null;
1064@@ -101,8 +97,8 @@
1065 return this.path;
1066 }
1067
1068- public Set<Key> getGameVersions() {
1069- return this.versions;
1070+ public GameVersionData getGameVersions() {
1071+ return this.version;
1072 }
1073
1074
1075@@ -139,23 +135,6 @@
1076 }
1077 */
1078
1079- public boolean addGameVersion(GameVersionData version) {
1080- // many-to-many relationship
1081- if (this.versions.add(version.getServerKey()))
1082- {
1083- return version.getGameFiles().add(this.getServerKey());
1084- }
1085- return false;
1086- }
1087-
1088- public boolean removeGameVersion(GameVersionData version) {
1089- // many-to-many relationship
1090- if (this.versions.remove(version.getServerKey()))
1091- {
1092- return version.getGameFiles().remove(this.getServerKey());
1093- }
1094- return false;
1095- }
1096
1097 /** TODO: Pending Blob implementation for files
1098 public GameFileData(String path, GameVersion version, InputStream contents) {
1099@@ -183,10 +162,6 @@
1100 public Class<GameFile> getClientClassType() {
1101 return GameFile.class;
1102 }
1103-
1104- public Set<Long> keysToGameVersions() {
1105- return this.fetchClientObjects(GameVersionData.class, this.versions);
1106- }
1107
1108 public String getBlobKeyString() {
1109 return this.blobKey.getKeyString();
1110
1111=== added file 'src/au/edu/unimelb/csse/mugle/server/model/GameFileGetter.java'
1112--- src/au/edu/unimelb/csse/mugle/server/model/GameFileGetter.java 1970-01-01 00:00:00 +0000
1113+++ src/au/edu/unimelb/csse/mugle/server/model/GameFileGetter.java 2011-04-29 07:02:27 +0000
1114@@ -0,0 +1,116 @@
1115+/* Melbourne University Game-based Learning Environment
1116+ * Copyright (C) 2011 The University of Melbourne
1117+ *
1118+ * This program is free software: you can redistribute it and/or modify
1119+ * it under the terms of the GNU General Public License as published by
1120+ * the Free Software Foundation, either version 3 of the License, or
1121+ * (at your option) any later version.
1122+ *
1123+ * This program is distributed in the hope that it will be useful,
1124+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1125+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1126+ * GNU General Public License for more details.
1127+ *
1128+ * You should have received a copy of the GNU General Public License
1129+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1130+ */
1131+
1132+package au.edu.unimelb.csse.mugle.server.model;
1133+
1134+import java.util.List;
1135+
1136+import javax.jdo.PersistenceManager;
1137+import javax.jdo.Query;
1138+
1139+import au.edu.unimelb.csse.mugle.server.PMF;
1140+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameFileNotExists;
1141+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameNotExists;
1142+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameVersionNotExists;
1143+
1144+public class GameFileGetter {
1145+ /**
1146+ * Gets the GameFile by its Primary Key - READ ONLY
1147+ * @param primaryKey
1148+ * @return the GameFile - read only
1149+ * @throws GameFileNotExists
1150+ */
1151+ public GameFileData getGameFile(Long primaryKey) throws GameFileNotExists {
1152+ PersistenceManager pm = PMF.getManager();
1153+ try {
1154+ return getGameFile(pm, primaryKey);
1155+ } finally {
1156+ pm.close();
1157+ }
1158+ }
1159+
1160+ /**
1161+ * Gets the GameFile by its Primary Key, for editing object in datastore
1162+ * PersistenceManager must be handled by the caller
1163+ * @param pm the PersistenceManager
1164+ * @param primaryKey
1165+ * @return the GameFile
1166+ * @throws GameFileNotExists
1167+ */
1168+ public GameFileData getGameFile(PersistenceManager pm, Long primaryKey) throws GameFileNotExists{
1169+ GameFileData gameFile = pm.getObjectById(GameFileData.class, primaryKey);
1170+
1171+ if(gameFile == null) {
1172+ throw new GameFileNotExists(primaryKey);
1173+ }
1174+
1175+ return gameFile;
1176+ }
1177+
1178+ /**
1179+ * Gets the GameFile by its path, version and game - READ ONLY
1180+ * @param gameName the name of the game
1181+ * @param gameVersion the version of the game
1182+ * @param path the path of the file
1183+ * @return the GameFile - read only
1184+ * @throws GameNotExists
1185+ * @throws GameVersionNotExists
1186+ * @throws GameFileNotExists
1187+ */
1188+ public GameFileData getGameFile(String gameName, String gameVersion, String path)
1189+ throws GameNotExists, GameVersionNotExists, GameFileNotExists {
1190+ PersistenceManager pm = PMF.getManager();
1191+ try {
1192+ return getGameFile(pm, gameName, gameVersion, path);
1193+ } finally {
1194+ pm.close();
1195+ }
1196+ }
1197+
1198+ /**
1199+ * Gets the GameFile by its path, version and game, for editing object in datastore
1200+ * PersistenceManager must be handled by the caller
1201+ * @para pm The Persistence Manager
1202+ * @param gameName the name of the game
1203+ * @param gameVersion the version of the game
1204+ * @param path the path of the file
1205+ * @return the GameFile - read only
1206+ * @throws GameNotExists
1207+ * @throws GameVersionNotExists
1208+ * @throws GameFileNotExists
1209+ */
1210+
1211+
1212+ @SuppressWarnings("unchecked")
1213+ public GameFileData getGameFile(PersistenceManager pm, String gameName, String gameVersion, String path)
1214+ throws GameFileNotExists, GameNotExists, GameVersionNotExists {
1215+ GameVersionGetter gvg = new GameVersionGetter();
1216+ GameVersionData gv = gvg.getGameVersion(pm, gameName, gameVersion);
1217+
1218+
1219+ Query q = pm.newQuery(GameFileData.class, "path == p && version == v");
1220+ q.declareParameters("String p, GameVersionData v");
1221+ List<GameFileData> results = (List<GameFileData>) q.execute(path, gv);
1222+
1223+ if (results.isEmpty()) {
1224+ throw new GameFileNotExists(gameName, gameVersion, path);
1225+ }
1226+
1227+ return results.get(0);
1228+ }
1229+
1230+}
1231
1232=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/GameVersionData.java'
1233--- src/au/edu/unimelb/csse/mugle/server/model/GameVersionData.java 2011-04-08 11:00:59 +0000
1234+++ src/au/edu/unimelb/csse/mugle/server/model/GameVersionData.java 2011-04-29 07:02:27 +0000
1235@@ -73,16 +73,15 @@
1236 @Element(dependent="true")
1237 private PromotedGameData promotedGame;
1238
1239- // Many-to-many
1240 @UserLevel(privateView=Role.DEVELOPER, publicView=Role.DEVELOPER, useMethod=true, mappedBy="keysToGameFiles")
1241- @Persistent
1242- private Set<Key> gameFiles;
1243+ @Persistent(mappedBy="version")
1244+ private Set<GameFileData> gameFiles;
1245
1246 // Constructors
1247
1248 public GameVersionData() {
1249
1250- this.gameFiles = new HashSet<Key>();
1251+ this.gameFiles = new HashSet<GameFileData>();
1252 this.promotedGame = null;
1253 this.game = null;
1254 //this.version = null;
1255@@ -98,7 +97,7 @@
1256 */
1257 public GameVersionData(GameData game, String displayVersion, String fullName, String description) {
1258
1259- this.gameFiles = new HashSet<Key>();
1260+ this.gameFiles = new HashSet<GameFileData>();
1261 this.promotedGame = null;
1262
1263 /* To be unique, the Primary key must be made up of the ID of the UGP and
1264@@ -142,7 +141,7 @@
1265 * }
1266 */
1267
1268- public Set<Key> getGameFiles() {
1269+ public Set<GameFileData> getGameFiles() {
1270 return this.gameFiles;
1271 }
1272
1273@@ -175,31 +174,6 @@
1274
1275 // TODO: setImage(Image image);
1276
1277-
1278- // Misc methods
1279-
1280- public boolean addGameFile(GameFileData file) {
1281- // many-to-many relationship
1282- if (this.gameFiles.add(file.getServerKey())) {
1283- return file.getGameVersions().add(this.getServerKey());
1284- }
1285- return false;
1286- }
1287-
1288- public boolean removeGameFile(GameFileData file) {
1289- // many-to-many relationship
1290- if (this.gameFiles.remove(file.getServerKey())) {
1291- if (file.getGameVersions().remove(this.getServerKey()))
1292- {
1293- // delete file if this is the only reference
1294- if (file.getGameVersions().isEmpty()) {
1295- // TODO: delete the file off the database
1296- // is this automatically done by GAE?
1297- }
1298- }
1299- }
1300- return false;
1301- }
1302
1303 @Override
1304 public Key getServerKey() {
1305@@ -225,9 +199,9 @@
1306 public Class<GameVersion> getClientClassType() {
1307 return GameVersion.class;
1308 }
1309-
1310+
1311 public Set<String> keysToGameFiles() {
1312- return this.fetchClientObjects(GameFileData.class, this.gameFiles);
1313+ return this.fetchClientObjects(this.gameFiles);
1314 }
1315
1316 }
1317
1318=== added file 'src/au/edu/unimelb/csse/mugle/server/model/GameVersionGetter.java'
1319--- src/au/edu/unimelb/csse/mugle/server/model/GameVersionGetter.java 1970-01-01 00:00:00 +0000
1320+++ src/au/edu/unimelb/csse/mugle/server/model/GameVersionGetter.java 2011-04-29 07:02:27 +0000
1321@@ -0,0 +1,107 @@
1322+/* Melbourne University Game-based Learning Environment
1323+ * Copyright (C) 2011 The University of Melbourne
1324+ *
1325+ * This program is free software: you can redistribute it and/or modify
1326+ * it under the terms of the GNU General Public License as published by
1327+ * the Free Software Foundation, either version 3 of the License, or
1328+ * (at your option) any later version.
1329+ *
1330+ * This program is distributed in the hope that it will be useful,
1331+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1332+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1333+ * GNU General Public License for more details.
1334+ *
1335+ * You should have received a copy of the GNU General Public License
1336+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1337+ */
1338+
1339+package au.edu.unimelb.csse.mugle.server.model;
1340+
1341+import java.util.List;
1342+
1343+import javax.jdo.PersistenceManager;
1344+import javax.jdo.Query;
1345+
1346+import au.edu.unimelb.csse.mugle.server.PMF;
1347+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameNotExists;
1348+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.GameVersionNotExists;
1349+
1350+public class GameVersionGetter {
1351+ /**
1352+ * Gets the GameVersion by its Primary Key - READ ONLY
1353+ * @param primaryKey
1354+ * @return the GameVersion - read only
1355+ * @throws GameVersionNotExists
1356+ */
1357+ public GameVersionData getGameVersion(Long primaryKey) throws GameVersionNotExists {
1358+ PersistenceManager pm = PMF.getManager();
1359+ try {
1360+ return getGameVersion(pm, primaryKey);
1361+ } finally {
1362+ pm.close();
1363+ }
1364+ }
1365+
1366+ /**
1367+ * Gets the GameVersion by its Primary Key, for editing object in datstore
1368+ * PersistenceManager must be handled by the caller
1369+ * @param pm the PersistenceManager
1370+ * @param primaryKey
1371+ * @return the GameVersion
1372+ * @throws GameVersionNotExists
1373+ */
1374+ public GameVersionData getGameVersion(PersistenceManager pm, Long primaryKey) throws GameVersionNotExists{
1375+ GameVersionData gameversion = pm.getObjectById(GameVersionData.class, primaryKey);
1376+
1377+ if(gameversion == null) {
1378+ throw new GameVersionNotExists(primaryKey);
1379+ }
1380+
1381+ return gameversion;
1382+ }
1383+
1384+ /**
1385+ * Gets the GameVersion by its display Version - READ ONLY
1386+ * @param gameName the name of the Game that it belongs to
1387+ * @param dispVersion the displayed version number
1388+ * @return the GameVersion - read only
1389+ * @throws GameVersionNotExists
1390+ */
1391+ public GameVersionData getGameVersion(String gameName, String dispVersion)
1392+ throws GameVersionNotExists, GameNotExists {
1393+ PersistenceManager pm = PMF.getManager();
1394+ try {
1395+ return getGameVersion(pm, gameName, dispVersion);
1396+ } finally {
1397+ pm.close();
1398+ }
1399+ }
1400+
1401+ /**
1402+ * Gets the GameVersion by its display name, for editing object in datastore
1403+ * PersistenceManager must be handled by the caller
1404+ * @param pm the PersistenceManager
1405+ * @param gameName the name of the Game that it belongs to
1406+ * @param dispVersion the displayed version number
1407+ * @return the GameVersion
1408+ * @throws GameVersionNotExists
1409+ * @throws GameNotExists
1410+ */
1411+ @SuppressWarnings("unchecked")
1412+ public GameVersionData getGameVersion(PersistenceManager pm, String gameName, String dispVersion)
1413+ throws GameVersionNotExists, GameNotExists{
1414+ GameGetter g = new GameGetter();
1415+ GameData game = g.getGame(pm, gameName);
1416+
1417+ Query q = pm.newQuery(GameData.class, "dispVersion == d && game == g");
1418+ q.declareParameters("String d, GameData g");
1419+ List<GameVersionData> results = (List<GameVersionData>) q.execute(dispVersion, game);
1420+
1421+ if(results.isEmpty()) {
1422+ throw new GameNotExists(dispVersion, game.getUrlName());
1423+ }
1424+
1425+ return results.get(0);
1426+ }
1427+}
1428+
1429
1430=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/KeyValuePairGetter.java'
1431--- src/au/edu/unimelb/csse/mugle/server/model/KeyValuePairGetter.java 2011-04-29 07:02:27 +0000
1432+++ src/au/edu/unimelb/csse/mugle/server/model/KeyValuePairGetter.java 2011-04-29 07:02:27 +0000
1433@@ -16,6 +16,8 @@
1434 */
1435 package au.edu.unimelb.csse.mugle.server.model;
1436
1437+import java.util.List;
1438+
1439 import javax.jdo.PersistenceManager;
1440 import javax.jdo.Query;
1441
1442@@ -37,7 +39,7 @@
1443 * @throws KeyError
1444 */
1445 public KeyValuePairData getKeyValuePair(String key, String gameToken)
1446- throws UserNotExists, GameTokenError, KeyError {
1447+ throws GameTokenError, KeyError {
1448 PersistenceManager pm = PMF.getManager();
1449 try {
1450 return getKeyValuePair(pm, key, gameToken);
1451@@ -60,7 +62,7 @@
1452 * @throws KeyError
1453 */
1454 public KeyValuePairData getKeyValuePair(PersistenceManager pm, String key, String gameToken)
1455- throws UserNotExists, GameTokenError, KeyError {
1456+ throws GameTokenError, KeyError {
1457 return getKeyValuePair(pm, key, gameToken, false);
1458 }
1459
1460@@ -79,30 +81,32 @@
1461 * @throws GameTokenError
1462 * @throws KeyError
1463 */
1464+ @SuppressWarnings("unchecked")
1465 public KeyValuePairData getKeyValuePair(PersistenceManager pm, String key, String gameToken, boolean createIfNotFound)
1466- throws UserNotExists, GameTokenError, KeyError {
1467+ throws GameTokenError, KeyError {
1468 UserGameProfileGetter u = new UserGameProfileGetter();
1469 UserGameProfileData ugp = u.getCurrentUserGameProfile(pm, gameToken);
1470
1471- KeyValuePairData kvp = null;
1472-
1473 Query q = pm.newQuery(KeyValuePairData.class, "key == k && ugp == u");
1474 q.declareParameters("String k, UserGameProfileData u");
1475- kvp = (KeyValuePairData) q.execute(key, ugp);
1476+ List<KeyValuePairData> results = (List<KeyValuePairData>) q.execute(key, ugp);
1477
1478 /* If the key value pair isn't found - we want to create one if
1479 * createIfNotFound is set to true
1480 */
1481- if (kvp == null) {
1482+ if (results.isEmpty()) {
1483 if (createIfNotFound) {
1484- kvp = new KeyValuePairData();
1485+ KeyValuePairData kvp = new KeyValuePairData();
1486 kvp.setKey(key);
1487 kvp.setUserGameProfile(ugp);
1488+ pm.makePersistent(kvp);
1489+
1490+ results.add(kvp);
1491 } else {
1492 throw new KeyError(key);
1493 }
1494 }
1495
1496- return kvp;
1497+ return results.get(0);
1498 }
1499 }
1500
1501=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/ModelDataClass.java'
1502--- src/au/edu/unimelb/csse/mugle/server/model/ModelDataClass.java 2011-04-29 07:02:27 +0000
1503+++ src/au/edu/unimelb/csse/mugle/server/model/ModelDataClass.java 2011-04-29 07:02:27 +0000
1504@@ -98,5 +98,17 @@
1505 return list;
1506
1507 }
1508+
1509+ protected <A, C extends ModelDataClass<A,?,C>> Set<A> fetchClientObjects(Set<C> dataList) {
1510+
1511+ HashSet<A> list = new HashSet<A>(dataList.size());
1512+
1513+ for (C cls : dataList) {
1514+ list.add(cls.getPrimaryKey());
1515+ }
1516+
1517+ return list;
1518+
1519+ }
1520
1521 }
1522
1523=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/ModelWrapper.java'
1524--- src/au/edu/unimelb/csse/mugle/server/model/ModelWrapper.java 2011-04-29 07:02:27 +0000
1525+++ src/au/edu/unimelb/csse/mugle/server/model/ModelWrapper.java 2011-04-29 07:02:27 +0000
1526@@ -20,11 +20,17 @@
1527 import java.lang.reflect.*;
1528
1529 import javax.jdo.PersistenceManager;
1530+import javax.jdo.Query;
1531+
1532+import com.google.appengine.api.users.User;
1533+import com.google.appengine.api.users.UserService;
1534+import com.google.appengine.api.users.UserServiceFactory;
1535
1536 import au.edu.unimelb.csse.mugle.server.model.annotations.*;
1537 import au.edu.unimelb.csse.mugle.server.PMF;
1538 import au.edu.unimelb.csse.mugle.shared.model.*;
1539 import au.edu.unimelb.csse.mugle.shared.model.annotations.*;
1540+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.ServerException;
1541 import au.edu.unimelb.csse.mugle.shared.platform.exceptions.UserPrivilegeException;
1542
1543 public final class ModelWrapper {
1544@@ -58,7 +64,7 @@
1545 case DEVELOPER:
1546 return (role == Role.ADMIN || role == Role.DEVELOPER);
1547
1548- case USER:
1549+ case GUEST:
1550 return true;
1551
1552 default:
1553@@ -168,8 +174,8 @@
1554 * @throws IllegalArgumentException
1555 * @throws NoSuchMethodException
1556 */
1557- public static <T extends ModelClass<?,T>, U extends ModelDataClass<?,T,U>, B extends ModelClass<?,B>, C extends ModelDataClass<?,B,C>>
1558- T getClientClone(U obj, Role role, ClientView cview)
1559+ public static <T extends ModelClass<?,T>, U extends ModelDataClass<?,T,U>>
1560+ T getClientClone(U obj, Role role, ClientView cview)
1561 throws InstantiationException, IllegalAccessException, SecurityException,
1562 NoSuchFieldException, NoSuchMethodException, IllegalArgumentException,
1563 InvocationTargetException {
1564@@ -230,6 +236,37 @@
1565 return stripped;
1566
1567 }
1568+
1569+ public static <T extends ModelClass<?,T>, U extends ModelDataClass<?,T,U>>
1570+ T getClientCloneSafe(U obj, Role role, ClientView cview)
1571+ throws ServerException {
1572+
1573+ try {
1574+ return getClientClone(obj, role, cview);
1575+ } catch (SecurityException e) {
1576+ e.printStackTrace();
1577+ throw new ServerException(e.getMessage());
1578+ } catch (IllegalArgumentException e) {
1579+ e.printStackTrace();
1580+ throw new ServerException(e.getMessage());
1581+ } catch (InstantiationException e) {
1582+ e.printStackTrace();
1583+ throw new ServerException(e.getMessage());
1584+ } catch (IllegalAccessException e) {
1585+ e.printStackTrace();
1586+ throw new ServerException(e.getMessage());
1587+ } catch (NoSuchFieldException e) {
1588+ e.printStackTrace();
1589+ throw new ServerException(e.getMessage());
1590+ } catch (NoSuchMethodException e) {
1591+ e.printStackTrace();
1592+ throw new ServerException(e.getMessage());
1593+ } catch (InvocationTargetException e) {
1594+ e.printStackTrace();
1595+ throw new ServerException(e.getMessage());
1596+ }
1597+
1598+ }
1599
1600 /**
1601 * Converts a ModelClass instance to its counter part ModelDataClass,
1602@@ -655,10 +692,22 @@
1603
1604
1605 // Current login privileges
1606-
1607+
1608 public static Role getCurrentRole() {
1609- // TODO needs to actually check login details and return the actual role.
1610- return Role.USER;
1611+
1612+ UserService userService = UserServiceFactory.getUserService();
1613+ User user = userService.getCurrentUser();
1614+
1615+ PersistenceManager pm = PMF.getManager();
1616+ if (pm == null) { return Role.NONE; }
1617+
1618+ Query q = pm.newQuery(UserData.class, "googleID == i || email == e");
1619+ q.declareParameters("String i, String e");
1620+ UserData ud = (UserData) q.execute(user.getUserId(), user.getEmail());
1621+ if (ud == null) { return Role.NONE; }
1622+
1623+ return ud.getRole();
1624+
1625 }
1626
1627 public static ClientView getCurrentClientView() {
1628
1629=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/UserAchievementGetter.java'
1630--- src/au/edu/unimelb/csse/mugle/server/model/UserAchievementGetter.java 2011-04-29 07:02:27 +0000
1631+++ src/au/edu/unimelb/csse/mugle/server/model/UserAchievementGetter.java 2011-04-29 07:02:27 +0000
1632@@ -17,6 +17,8 @@
1633
1634 package au.edu.unimelb.csse.mugle.server.model;
1635
1636+import java.util.List;
1637+
1638 import javax.jdo.PersistenceManager;
1639 import javax.jdo.Query;
1640
1641@@ -37,7 +39,7 @@
1642 * @throws AchievementNotExists
1643 */
1644 public UserAchievementData getUserAchievement(String achievementName, String gameToken)
1645- throws UserNotExists, GameTokenError, AchievementNotExists {
1646+ throws GameTokenError, AchievementNotExists {
1647 PersistenceManager pm = PMF.getManager();
1648 try {
1649 return getUserAchievement(pm, achievementName, gameToken);
1650@@ -58,8 +60,9 @@
1651 * @throws GameTokenError
1652 * @throws AchievementNotExists
1653 */
1654+ @SuppressWarnings("unchecked")
1655 public UserAchievementData getUserAchievement(PersistenceManager pm, String achievementName, String gameToken)
1656- throws UserNotExists, GameTokenError, AchievementNotExists {
1657+ throws GameTokenError, AchievementNotExists {
1658 UserGameProfileGetter u = new UserGameProfileGetter();
1659 AchievementGetter a = new AchievementGetter();
1660
1661@@ -68,17 +71,20 @@
1662
1663 Query q = pm.newQuery(UserAchievementData.class, "ugp == u && achievement == a");
1664 q.declareParameters("UserGameProfileData ugp, AchievementData a");
1665- UserAchievementData ua = (UserAchievementData) q.execute(ugp, achievement);
1666+ List<UserAchievementData> results = (List<UserAchievementData>) q.execute(ugp, achievement);
1667
1668 /* If we can't find the UserAchievement it makes sense to create one
1669 * if the UserGameProfile and the Achievement exist.
1670 */
1671- if (ua == null) {
1672- ua = new UserAchievementData();
1673+ if (results.isEmpty()) {
1674+ UserAchievementData ua = new UserAchievementData();
1675 ua.setAchievement(achievement);
1676 ua.setUserGameProfile(ugp);
1677+ pm.makePersistent(ua);
1678+
1679+ results.add(ua);
1680 }
1681
1682- return ua;
1683+ return results.get(0);
1684 }
1685 }
1686
1687=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/UserGameProfileGetter.java'
1688--- src/au/edu/unimelb/csse/mugle/server/model/UserGameProfileGetter.java 2011-04-29 07:02:27 +0000
1689+++ src/au/edu/unimelb/csse/mugle/server/model/UserGameProfileGetter.java 2011-04-29 07:02:27 +0000
1690@@ -17,6 +17,8 @@
1691
1692 package au.edu.unimelb.csse.mugle.server.model;
1693
1694+import java.util.List;
1695+
1696 import javax.jdo.PersistenceManager;
1697 import javax.jdo.Query;
1698
1699@@ -68,7 +70,7 @@
1700 * @throws GameTokenError
1701 */
1702 public UserGameProfileData getCurrentUserGameProfile(String gameToken)
1703- throws UserNotExists, GameTokenError {
1704+ throws GameTokenError {
1705 PersistenceManager pm = PMF.getManager();
1706 try {
1707 return getCurrentUserGameProfile(pm, gameToken);
1708@@ -87,27 +89,31 @@
1709 * @throws UserNotExists
1710 * @throws GameTokenError
1711 */
1712+ @SuppressWarnings("unchecked")
1713 public UserGameProfileData getCurrentUserGameProfile(PersistenceManager pm, String gameToken)
1714- throws UserNotExists, GameTokenError {
1715+ throws GameTokenError {
1716 UserGetter u = new UserGetter();
1717 GameGetter g = new GameGetter();
1718 UserData curUser = u.getCurrentUser(pm);
1719 GameData curGame = g.getCurrentGame(pm, gameToken);
1720- UserGameProfileData ugp = null;
1721+
1722
1723 Query q = pm.newQuery(UserGameProfileData.class, "user == u && game == g");
1724 q.declareParameters("UserData u, GameData g");
1725- ugp = (UserGameProfileData) q.execute(curUser, curGame);
1726+ List<UserGameProfileData> results = (List<UserGameProfileData>) q.execute(curUser, curGame);
1727
1728 /* If we can't find the UserGameProfile it makes sense to create one
1729 * if the user is playing the game
1730 */
1731- if (ugp == null) {
1732- ugp = new UserGameProfileData();
1733+ if (results.isEmpty()) {
1734+ UserGameProfileData ugp = new UserGameProfileData();
1735 ugp.setGame(curGame);
1736 ugp.setUser(curUser);
1737+ pm.makePersistent(ugp);
1738+
1739+ results.add(ugp);
1740 }
1741- return ugp;
1742+ return results.get(0);
1743 }
1744
1745 }
1746
1747=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/UserGetter.java'
1748--- src/au/edu/unimelb/csse/mugle/server/model/UserGetter.java 2011-04-29 07:02:27 +0000
1749+++ src/au/edu/unimelb/csse/mugle/server/model/UserGetter.java 2011-04-29 07:02:27 +0000
1750@@ -20,9 +20,12 @@
1751 import javax.jdo.PersistenceManager;
1752 import javax.jdo.Query;
1753
1754+import java.util.List;
1755+
1756 import au.edu.unimelb.csse.mugle.client.LoginInfo;
1757-import au.edu.unimelb.csse.mugle.server.LoginServiceImpl;
1758+import au.edu.unimelb.csse.mugle.server.ClientServiceImpl;
1759 import au.edu.unimelb.csse.mugle.server.PMF;
1760+import au.edu.unimelb.csse.mugle.shared.model.Role;
1761 import au.edu.unimelb.csse.mugle.shared.platform.exceptions.UserNotExists;
1762
1763 public class UserGetter {
1764@@ -82,16 +85,17 @@
1765 * @return The User class
1766 * @throws UserNotExists
1767 */
1768+ @SuppressWarnings("unchecked")
1769 public UserData getUserByName(PersistenceManager pm, String name) throws UserNotExists {
1770 Query q = pm.newQuery(UserData.class, "urlName == u");
1771 q.declareParameters("String u");
1772- UserData u = (UserData) q.execute(name);
1773+ List<UserData> results = (List<UserData>) q.execute(name);
1774
1775- if (u == null) {
1776+ if (results.isEmpty()) {
1777 throw new UserNotExists(name);
1778 }
1779
1780- return u;
1781+ return results.get(0);
1782 }
1783
1784 /**
1785@@ -117,24 +121,24 @@
1786 * @return The User class
1787 * @throws UserNotExists
1788 */
1789+ @SuppressWarnings("unchecked")
1790 public UserData getUser(PersistenceManager pm, String googleID) throws UserNotExists {
1791 Query q = pm.newQuery(UserData.class, "googleID == u");
1792 q.declareParameters("String u");
1793- UserData u = (UserData) q.execute(googleID);
1794+ List<UserData> results = (List<UserData>) q.execute(googleID);
1795
1796- if (u == null) {
1797+ if (results.isEmpty()) {
1798 throw new UserNotExists(googleID);
1799 }
1800
1801- return u;
1802+ return results.get(0);
1803 }
1804
1805 /**
1806 * Gets the currently logged in User - READ ONLY
1807 * @return the User - read only
1808- * @throws UserNotExists
1809 */
1810- public UserData getCurrentUser() throws UserNotExists {
1811+ public UserData getCurrentUser() {
1812 PersistenceManager pm = PMF.getManager();
1813 try {
1814 return getCurrentUser(pm);
1815@@ -144,17 +148,35 @@
1816 }
1817
1818 /**
1819- * Gets the currently logged in User, for editing object in datstore
1820+ * Gets the currently logged in User, for editing object in datastore
1821+ * Creates a new user if the currently logged in user is not found
1822 * Persistence Manager must be handled by the caller
1823 * @param pm The Persistence Manager
1824 * @return the current User
1825- * @throws UserNotExists
1826 */
1827- public UserData getCurrentUser(PersistenceManager pm) throws UserNotExists {
1828- LoginServiceImpl loginService = new LoginServiceImpl();
1829+ public UserData getCurrentUser(PersistenceManager pm) {
1830+ ClientServiceImpl loginService = new ClientServiceImpl();
1831 LoginInfo loginInfo = loginService.getCurrentUser();
1832
1833- return getUser(pm, loginInfo.getUserID());
1834+ try {
1835+ return getUser(pm, loginInfo.getUserID());
1836+ } catch (UserNotExists e) {
1837+ UserData newUser = new UserData();
1838+
1839+ //Creates the new user using the info provided by google
1840+ newUser.setGoogleID(loginInfo.getUserID());
1841+ newUser.setUrlName(loginInfo.getNickname());
1842+ newUser.setFullName(loginInfo.getNickname());
1843+ newUser.setEmail(loginInfo.getEmailAddress());
1844+ newUser.setRole(Role.DEVELOPER);
1845+ newUser.setActive(true);
1846+
1847+ //Stores the new user in the datastore
1848+ pm.makePersistent(newUser);
1849+
1850+ return newUser;
1851+ }
1852+
1853 }
1854
1855 }
1856
1857=== modified file 'src/au/edu/unimelb/csse/mugle/server/model/annotations/UserLevel.java'
1858--- src/au/edu/unimelb/csse/mugle/server/model/annotations/UserLevel.java 2011-03-31 09:56:28 +0000
1859+++ src/au/edu/unimelb/csse/mugle/server/model/annotations/UserLevel.java 2011-04-29 07:02:27 +0000
1860@@ -27,8 +27,8 @@
1861 @Target(ElementType.FIELD)
1862 @Retention(RetentionPolicy.RUNTIME)
1863 public @interface UserLevel {
1864- Role privateView() default Role.USER;
1865- Role publicView() default Role.USER;
1866+ Role privateView() default Role.GUEST;
1867+ Role publicView() default Role.GUEST;
1868 boolean useMethod() default false;
1869 boolean mapField() default true;
1870 String mappedBy() default "";
1871
1872=== modified file 'src/au/edu/unimelb/csse/mugle/server/platform/DeveloperServiceImpl.java'
1873--- src/au/edu/unimelb/csse/mugle/server/platform/DeveloperServiceImpl.java 2011-04-29 07:02:27 +0000
1874+++ src/au/edu/unimelb/csse/mugle/server/platform/DeveloperServiceImpl.java 2011-04-29 07:02:27 +0000
1875@@ -23,7 +23,7 @@
1876 import au.edu.unimelb.csse.mugle.shared.platform.exceptions.*;
1877
1878 @SuppressWarnings("serial")
1879-public class DeveloperServiceImpl extends UserServiceImpl implements DeveloperService {
1880+public class DeveloperServiceImpl extends GuestServiceImpl implements DeveloperService {
1881
1882 @Override
1883 public GameVersion addGameVersion(GameVersion gameVersion)
1884
1885=== renamed file 'src/au/edu/unimelb/csse/mugle/server/platform/UserServiceImpl.java' => 'src/au/edu/unimelb/csse/mugle/server/platform/GuestServiceImpl.java'
1886--- src/au/edu/unimelb/csse/mugle/server/platform/UserServiceImpl.java 2011-03-26 14:01:07 +0000
1887+++ src/au/edu/unimelb/csse/mugle/server/platform/GuestServiceImpl.java 2011-04-29 07:02:27 +0000
1888@@ -19,9 +19,21 @@
1889
1890 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
1891
1892-import au.edu.unimelb.csse.mugle.client.platform.UserService;
1893+import au.edu.unimelb.csse.mugle.client.platform.GuestService;
1894+import au.edu.unimelb.csse.mugle.server.model.*;
1895+import au.edu.unimelb.csse.mugle.shared.model.*;
1896+import au.edu.unimelb.csse.mugle.shared.platform.exceptions.ServerException;
1897
1898 @SuppressWarnings("serial")
1899-public class UserServiceImpl extends RemoteServiceServlet implements UserService {
1900+public class GuestServiceImpl extends RemoteServiceServlet implements GuestService {
1901+
1902+ @Override
1903+ public User getCurrentUserDetails() throws ServerException {
1904+
1905+ UserGetter u = new UserGetter();
1906+ UserData ud = u.getCurrentUser();
1907+
1908+ return ModelWrapper.getClientCloneSafe(ud, ud.getRole(), ClientView.PRIVATE);
1909+ }
1910
1911 }
1912
1913=== modified file 'src/au/edu/unimelb/csse/mugle/shared/model/DataServiceAsync.java'
1914--- src/au/edu/unimelb/csse/mugle/shared/model/DataServiceAsync.java 2011-04-08 09:52:55 +0000
1915+++ src/au/edu/unimelb/csse/mugle/shared/model/DataServiceAsync.java 2011-04-29 07:02:27 +0000
1916@@ -26,7 +26,7 @@
1917
1918 void fetchDevTeams(Set<Long> keys, AsyncCallback<Set<DevTeam>> callback);
1919
1920- void fetchGameFiles(Set<String> keys, AsyncCallback<Set<GameFile>> callback);
1921+ void fetchGameFiles(Set<Long> keys, AsyncCallback<Set<GameFile>> callback);
1922
1923 void fetchGames(Set<Long> keys, AsyncCallback<Set<Game>> callback);
1924
1925
1926=== modified file 'src/au/edu/unimelb/csse/mugle/shared/model/GameFile.java'
1927--- src/au/edu/unimelb/csse/mugle/shared/model/GameFile.java 2011-04-29 07:02:27 +0000
1928+++ src/au/edu/unimelb/csse/mugle/shared/model/GameFile.java 2011-04-29 07:02:27 +0000
1929@@ -17,10 +17,6 @@
1930
1931 package au.edu.unimelb.csse.mugle.shared.model;
1932
1933-import java.util.Set;
1934-
1935-import com.google.gwt.user.client.rpc.AsyncCallback;
1936-
1937 import au.edu.unimelb.csse.mugle.shared.model.annotations.*;
1938
1939 @MugleDataWrapper
1940@@ -36,11 +32,11 @@
1941
1942 private String blobKey; //key to the actual blob
1943
1944- private Set<Long> gameVersionKeys; //Game versions this file belongs to
1945+ private GameVersion version; //Game versions this file belongs to
1946
1947 // Constructors
1948 public GameFile() {
1949- this.gameVersionKeys = null;
1950+ this.version = null;
1951 this.mimeType = null;
1952 this.blobKey = null;
1953 this.path = null;
1954@@ -52,12 +48,8 @@
1955 return this.path;
1956 }
1957
1958- public Set<Long> getGameVersionKeys() {
1959- return this.gameVersionKeys;
1960- }
1961-
1962- public void fetchGameVersions(AsyncCallback<Set<GameVersion>> callback) {
1963- DataProvider.getService().fetchGameVersions(this.gameVersionKeys, callback);
1964+ public GameVersion getGameVersionKeys() {
1965+ return this.version;
1966 }
1967
1968 @Override
1969@@ -71,8 +63,8 @@
1970 this.path = path;
1971 }
1972
1973- public void setGameVersionKeys(Set<Long> versions) {
1974- this.gameVersionKeys = versions;
1975+ public void setGameVersionKeys(GameVersion version) {
1976+ this.version = version;
1977 }
1978
1979 public void setMimeType(String mimeType) {
1980
1981=== modified file 'src/au/edu/unimelb/csse/mugle/shared/model/GameVersion.java'
1982--- src/au/edu/unimelb/csse/mugle/shared/model/GameVersion.java 2011-04-29 07:02:27 +0000
1983+++ src/au/edu/unimelb/csse/mugle/shared/model/GameVersion.java 2011-04-29 07:02:27 +0000
1984@@ -49,7 +49,7 @@
1985
1986 private PromotedGame promotedGame;
1987
1988- private Set<String> gameFileKeys;
1989+ private Set<Long> gameFileKeys;
1990
1991 // Constructors
1992
1993@@ -95,7 +95,7 @@
1994 return this.promotedGame;
1995 }
1996
1997- public Set<String> getGameFileKeys() {
1998+ public Set<Long> getGameFileKeys() {
1999 return this.gameFileKeys;
2000 }
2001
2002@@ -130,7 +130,7 @@
2003 this.promotedGame = promotedGame;
2004 }
2005
2006- public void setGameFileKeys(Set<String> gameFiles) {
2007+ public void setGameFileKeys(Set<Long> gameFiles) {
2008 this.gameFileKeys = gameFiles;
2009 }
2010
2011
2012=== modified file 'src/au/edu/unimelb/csse/mugle/shared/model/ModelClass.java'
2013--- src/au/edu/unimelb/csse/mugle/shared/model/ModelClass.java 2011-03-30 15:46:59 +0000
2014+++ src/au/edu/unimelb/csse/mugle/shared/model/ModelClass.java 2011-04-29 07:02:27 +0000
2015@@ -19,17 +19,20 @@
2016
2017 import java.io.Serializable;
2018
2019+import com.google.gwt.user.client.rpc.IsSerializable;
2020+
2021 /**
2022 * Base model class that should be extended by all shared model class entities.
2023 * @param <S> The primary key type
2024 * @param <T> The client class type (usually self type)
2025 * @param <U> The server class type (usually the data counter part type)
2026 */
2027-@SuppressWarnings("serial")
2028-public abstract class ModelClass<S,T extends ModelClass<S,?>> implements Serializable {
2029-
2030
2031- private S id = null;
2032+public abstract class ModelClass<S,T extends ModelClass<S,?>> implements Serializable, IsSerializable {
2033+
2034+ private static final long serialVersionUID = -2271296896173152105L;
2035+
2036+ private S id = null;
2037
2038 /**
2039 * The getter for the primary key
2040
2041=== modified file 'src/au/edu/unimelb/csse/mugle/shared/model/Role.java'
2042--- src/au/edu/unimelb/csse/mugle/shared/model/Role.java 2011-03-10 04:56:07 +0000
2043+++ src/au/edu/unimelb/csse/mugle/shared/model/Role.java 2011-04-29 07:02:27 +0000
2044@@ -18,5 +18,5 @@
2045 package au.edu.unimelb.csse.mugle.shared.model;
2046
2047 public enum Role {
2048- USER, DEVELOPER, ADMIN;
2049+ NONE, GUEST, DEVELOPER, ADMIN;
2050 }
2051
2052=== modified file 'src/au/edu/unimelb/csse/mugle/shared/model/annotations/MugleDataWrapper.java'
2053--- src/au/edu/unimelb/csse/mugle/shared/model/annotations/MugleDataWrapper.java 2011-03-30 15:46:59 +0000
2054+++ src/au/edu/unimelb/csse/mugle/shared/model/annotations/MugleDataWrapper.java 2011-04-29 07:02:27 +0000
2055@@ -31,10 +31,10 @@
2056 @Target(ElementType.TYPE)
2057 @Retention(RetentionPolicy.RUNTIME)
2058 public @interface MugleDataWrapper {
2059- Role privateAdd() default Role.USER;
2060- Role privateUpdate() default Role.USER;
2061- Role privateRemove() default Role.USER;
2062- Role publicAdd() default Role.USER;
2063- Role publicUpdate() default Role.USER;
2064- Role publicRemove() default Role.USER;
2065+ Role privateAdd() default Role.GUEST;
2066+ Role privateUpdate() default Role.GUEST;
2067+ Role privateRemove() default Role.GUEST;
2068+ Role publicAdd() default Role.GUEST;
2069+ Role publicUpdate() default Role.GUEST;
2070+ Role publicRemove() default Role.GUEST;
2071 }
2072
2073=== added file 'src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/GameFileNotExists.java'
2074--- src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/GameFileNotExists.java 1970-01-01 00:00:00 +0000
2075+++ src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/GameFileNotExists.java 2011-04-29 07:02:27 +0000
2076@@ -0,0 +1,22 @@
2077+package au.edu.unimelb.csse.mugle.shared.platform.exceptions;
2078+
2079+public class GameFileNotExists extends Exception{
2080+
2081+ /**
2082+ *
2083+ */
2084+ private static final long serialVersionUID = 728229816363066583L;
2085+
2086+ public GameFileNotExists() {
2087+ super();
2088+ }
2089+
2090+ public GameFileNotExists(Long primaryKey) {
2091+ super("The gameFile with primary key " + primaryKey.toString() + " does not exist");
2092+ }
2093+
2094+ public GameFileNotExists(String gameName, String gameVersion, String path) {
2095+ super("The file " + path + " for the version " + gameVersion +
2096+ " of " + gameName + " does not Exist.");
2097+ }
2098+}
2099
2100=== modified file 'src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/GameNotExists.java'
2101--- src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/GameNotExists.java 2011-04-29 07:02:27 +0000
2102+++ src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/GameNotExists.java 2011-04-29 07:02:27 +0000
2103@@ -46,5 +46,9 @@
2104 public GameNotExists(Long id) {
2105 super("Game with ID '" + id + "' does not exist.");
2106 }
2107+
2108+ public GameNotExists(String dispVersion, String gameName) {
2109+ super("Game " + gameName + " does not have version " + dispVersion + ".");
2110+ }
2111
2112 }
2113\ No newline at end of file
2114
2115=== added file 'src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/ServerException.java'
2116--- src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/ServerException.java 1970-01-01 00:00:00 +0000
2117+++ src/au/edu/unimelb/csse/mugle/shared/platform/exceptions/ServerException.java 2011-04-29 07:02:27 +0000
2118@@ -0,0 +1,34 @@
2119+/* Melbourne University Game-based Learning Environment
2120+ * Copyright (C) 2011 The University of Melbourne
2121+ *
2122+ * This program is free software: you can redistribute it and/or modify
2123+ * it under the terms of the GNU General Public License as published by
2124+ * the Free Software Foundation, either version 3 of the License, or
2125+ * (at your option) any later version.
2126+ *
2127+ * This program is distributed in the hope that it will be useful,
2128+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2129+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2130+ * GNU General Public License for more details.
2131+ *
2132+ * You should have received a copy of the GNU General Public License
2133+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2134+ */
2135+
2136+package au.edu.unimelb.csse.mugle.shared.platform.exceptions;
2137+
2138+import java.io.Serializable;
2139+
2140+public class ServerException extends Exception implements Serializable {
2141+
2142+ private static final long serialVersionUID = -5641489622969459865L;
2143+
2144+ public ServerException() {
2145+ super();
2146+ }
2147+
2148+ public ServerException(final String msg) {
2149+ super(msg);
2150+ }
2151+
2152+}
2153
2154=== modified file 'war/Mugle.css'
2155--- war/Mugle.css 2011-04-08 11:51:46 +0000
2156+++ war/Mugle.css 2011-04-29 07:02:27 +0000
2157@@ -1,7 +1,8 @@
2158 /** Add css rules here for your application. */
2159
2160 body {
2161- min-width: 600px;
2162+ min-width: 1000px;
2163+ background: white;
2164 }
2165
2166 h1 {
2167@@ -12,54 +13,103 @@
2168 text-align: center;
2169 }
2170
2171+#container {
2172+ min-height: 100%;
2173+ width: 100%;
2174+ position: relative;
2175+ float: left;
2176+}
2177+
2178+/* HEADER */
2179+
2180 #user-panel-container {
2181 height: 25px;
2182 border-bottom: #b6bac0 1px solid;
2183 margin: 0;
2184- padding: 0 5px;
2185- background-color: #ffffff;
2186+ padding: 0;
2187+ background: white;
2188+ position: relative;
2189+ float: left;
2190+ width: 100%;
2191 }
2192
2193 #user-panel-title {
2194 height: 25px;
2195 width:50px;
2196- margin: 0;
2197+ margin: 5px 5px 0 5px;
2198 padding: 0;
2199 float: left;
2200- padding-top: 5px;
2201 }
2202
2203 #user-panel-holder {
2204 height: 25px;
2205 margin: 0;
2206- padding: 0;
2207+ padding: 0 5px;
2208 float: right;
2209 text-align: : right;
2210 }
2211
2212+/* BODY */
2213+
2214 #main-panel {
2215- text-align: center;
2216- min-height:500px;
2217- height:100%;
2218- background-color: #ffffff;
2219-}
2220-
2221-table#tools-panel {
2222- position: absolute;
2223- left: 0;
2224- top: 25px;
2225- width: 250px;
2226-}
2227-
2228-#error-display {
2229- background-color: #ffffff;
2230+ padding:0;
2231+ padding-bottom:100px; /* Height of the footer */
2232+ background:white;
2233+ position: relative;
2234+ float: left;
2235 width: 100%;
2236 }
2237
2238+#main-panel-container {
2239+ clear:left;
2240+ float:left;
2241+ width:100%;
2242+ overflow:hidden;
2243+ background:white; /* column 2 background colour */
2244+}
2245+
2246+#main-panel-container-inner {
2247+ float:left;
2248+ width:100%;
2249+ position:relative;
2250+ right:80%;
2251+ background:white; /* column 1 background colour */
2252+ border-right: #b6bac0 1px solid;
2253+ min-height: 500px;
2254+}
2255+
2256+#tools-panel {
2257+ float:left;
2258+ width:20%;
2259+ position:relative;
2260+ left:80%;
2261+ overflow:hidden;
2262+}
2263+
2264+#right-panel {
2265+ float:left;
2266+ width:80%;
2267+ position:relative;
2268+ left:80%;
2269+ overflow:hidden;
2270+}
2271+
2272+#right-panel-inner {
2273+ float:left;
2274+ width:100%;
2275+ margin:5px;
2276+}
2277+
2278+/* FOOTER */
2279+
2280 #footer {
2281+ position:absolute;
2282+ /*position: relative;*/
2283+ width: 100%;
2284+ bottom: 0;
2285 text-align: center;
2286 background: #01467d url('img/footer-top.png') top center repeat-x;
2287- height: 100px;
2288+ height: 100px; /* Height of the footer */
2289 }
2290
2291 #footer-banner {
2292@@ -80,6 +130,11 @@
2293 float: right;
2294 }
2295
2296+#error-display {
2297+ background-color: #ffffff;
2298+ width: 100%;
2299+}
2300+
2301 .sendButton {
2302 display: block;
2303 font-size: 16pt;
2304
2305=== modified file 'war/Mugle.html'
2306--- war/Mugle.html 2011-04-02 04:18:20 +0000
2307+++ war/Mugle.html 2011-04-29 07:02:27 +0000
2308@@ -30,7 +30,10 @@
2309 <!-- Consider inlining CSS to reduce the number of requested files -->
2310 <!-- -->
2311 <link type="text/css" rel="stylesheet" href="Mugle.css">
2312-
2313+ <!--[if lte IE 6]>
2314+ <link type="text/css" rel="stylesheet" href="MugleIE6.css">
2315+ <![endif]-->
2316+
2317 <!-- -->
2318 <!-- Any title is fine -->
2319 <!-- -->
2320@@ -62,28 +65,34 @@
2321 </div>
2322 </noscript>
2323
2324- <div id="user-panel-container">
2325- <div id="user-panel-title"></div>
2326- <div id="user-panel-holder"></div>
2327- </div>
2328-
2329- <div id="main-panel"></div>
2330-
2331- <table id="error-display" align="center">
2332- <tr>
2333- <td colspan="2" style="color:red;" id="errorLabelContainer"></td>
2334- </tr>
2335- </table>
2336-
2337- <div id="footer">
2338- <div id="footer-banner">
2339- <a id="unimelb-logo" href="http://www.unimelb.edu.au" title="University of Melbourne" target="_blank">
2340- <img src="img/unimelb.png"></img>
2341- </a>
2342- <div id="footer-content">
2343- <!-- Add copyright details, etc -->
2344- </div>
2345- </div>
2346+ <div id="container">
2347+
2348+ <div id="user-panel-container">
2349+ <div id="user-panel-title"></div>
2350+ <div id="user-panel-holder"></div>
2351+ </div>
2352+
2353+ <div id="main-panel">
2354+ <!-- All GWT elements gets added/removed in here. -->
2355+ </div>
2356+
2357+ <table id="error-display" align="center">
2358+ <tr>
2359+ <td colspan="2" style="color:red;" id="errorLabelContainer"></td>
2360+ </tr>
2361+ </table>
2362+
2363+ <div id="footer">
2364+ <div id="footer-banner">
2365+ <a id="unimelb-logo" href="http://www.unimelb.edu.au" title="University of Melbourne" target="_blank">
2366+ <img src="img/unimelb.png"></img>
2367+ </a>
2368+ <div id="footer-content">
2369+ <!-- Add copyright details, etc -->
2370+ </div>
2371+ </div>
2372+ </div>
2373+
2374 </div>
2375
2376 </body>
2377
2378=== added file 'war/MugleIE6.css'
2379--- war/MugleIE6.css 1970-01-01 00:00:00 +0000
2380+++ war/MugleIE6.css 2011-04-29 07:02:27 +0000
2381@@ -0,0 +1,3 @@
2382+#container {
2383+ height:100%;
2384+}
2385\ No newline at end of file
2386
2387=== modified file 'war/WEB-INF/web.xml'
2388--- war/WEB-INF/web.xml 2011-04-29 07:02:27 +0000
2389+++ war/WEB-INF/web.xml 2011-04-29 07:02:27 +0000
2390@@ -12,13 +12,13 @@
2391 <!-- Servlets -->
2392
2393 <servlet>
2394- <servlet-name>LoginService</servlet-name>
2395- <servlet-class>au.edu.unimelb.csse.mugle.server.LoginServiceImpl</servlet-class>
2396+ <servlet-name>ClientService</servlet-name>
2397+ <servlet-class>au.edu.unimelb.csse.mugle.server.ClientServiceImpl</servlet-class>
2398 </servlet>
2399
2400 <servlet-mapping>
2401- <servlet-name>LoginService</servlet-name>
2402- <url-pattern>/mugle/login</url-pattern>
2403+ <servlet-name>ClientService</servlet-name>
2404+ <url-pattern>/mugle/client</url-pattern>
2405 </servlet-mapping>
2406
2407 <servlet>
2408@@ -52,13 +52,13 @@
2409 </servlet-mapping>
2410
2411 <servlet>
2412- <servlet-name>UserService</servlet-name>
2413- <servlet-class>au.edu.unimelb.csse.mugle.server.platform.UserServiceImpl</servlet-class>
2414+ <servlet-name>GuestService</servlet-name>
2415+ <servlet-class>au.edu.unimelb.csse.mugle.server.platform.GuestServiceImpl</servlet-class>
2416 </servlet>
2417
2418 <servlet-mapping>
2419- <servlet-name>UserService</servlet-name>
2420- <url-pattern>/mugle/users</url-pattern>
2421+ <servlet-name>GuestService</servlet-name>
2422+ <url-pattern>/mugle/guests</url-pattern>
2423 </servlet-mapping>
2424
2425 <servlet>

Subscribers

People subscribed via source and target branches