resty-generators 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/features/generators.feature +67 -0
  2. data/features/step_definitions/simple_steps.rb +1 -0
  3. data/lib/generators/resty/base.rb +15 -3
  4. data/lib/generators/resty/model/model_generator.rb +33 -3
  5. data/lib/generators/resty/scaffold/scaffold_generator.rb +30 -15
  6. data/lib/generators/resty/setup/setup_generator.rb +2 -2
  7. data/lib/generators/resty/setup/setup_generator.rb~ +31 -0
  8. data/lib/generators/resty/setup/templates/ActivityFactory.java~ +7 -0
  9. data/lib/generators/resty/setup/templates/ActivityPlace.java +5 -0
  10. data/lib/generators/resty/setup/templates/ActivityPlace.java~ +8 -0
  11. data/lib/generators/resty/setup/templates/BreadCrumbsPanel.java +3 -2
  12. data/lib/generators/resty/setup/templates/BreadCrumbsPanel.java~ +79 -0
  13. data/lib/generators/resty/setup/templates/GinModule.java~ +7 -0
  14. data/lib/generators/resty/setup/templates/LoginActivity.java~ +58 -0
  15. data/lib/generators/resty/setup/templates/LoginPlace.java~ +20 -0
  16. data/lib/generators/resty/setup/templates/LoginViewImpl.java~ +21 -0
  17. data/lib/generators/resty/setup/templates/Mavenfile +5 -5
  18. data/lib/generators/resty/setup/templates/Mavenfile~ +15 -0
  19. data/lib/generators/resty/setup/templates/MenuPanel.java~ +12 -0
  20. data/lib/generators/resty/setup/templates/PLaceHistoryMapper.java~ +7 -0
  21. data/lib/generators/resty/setup/templates/RestfulPlace.java~ +22 -0
  22. data/lib/generators/resty/setup/templates/SessionActivityPlaceActivityMapper.java~ +71 -0
  23. data/lib/generators/resty/setup/templates/SessionRestService.java~ +23 -0
  24. data/lib/generators/resty/setup/templates/User.java +34 -4
  25. data/lib/generators/resty/setup/templates/authentication.rb +2 -1
  26. data/lib/generators/resty/setup/templates/authentication.rb~ +4 -0
  27. data/lib/generators/resty/setup/templates/empty.css~ +1 -0
  28. data/lib/generators/resty/setup/templates/gwt.css +45 -0
  29. data/lib/generators/resty/setup/templates/initializer.rb~ +1 -0
  30. data/lib/generators/resty/setup/templates/monkey_patch.rb~ +27 -0
  31. data/lib/generators/resty/setup/templates/page.html~ +0 -0
  32. data/lib/generators/resty/setup/templates/session.rb +18 -36
  33. data/lib/generators/resty/setup/templates/session.rb~ +45 -0
  34. data/lib/generators/resty/setup/templates/sessions_controller.rb +27 -8
  35. data/lib/generators/resty/setup/templates/sessions_controller.rb~ +27 -0
  36. data/lib/generators/resty/setup/templates/user.rb +38 -6
  37. data/lib/generators/resty/setup/templates/user.rb~ +27 -0
  38. data/lib/generators/resty/templates/Activity.java +78 -39
  39. data/lib/generators/resty/templates/Activity.java~ +67 -0
  40. data/lib/generators/resty/templates/ActivityPlace.java~ +11 -0
  41. data/lib/generators/resty/templates/ColumnDefinitionsImpl.java~ +24 -0
  42. data/lib/generators/resty/templates/ColumnDefintionsImpl.java~ +34 -0
  43. data/lib/generators/resty/templates/Controller.java~ +49 -0
  44. data/lib/generators/resty/templates/Editor.java +123 -0
  45. data/lib/generators/resty/templates/Editor.java~ +84 -0
  46. data/lib/generators/resty/templates/Editor.ui.xml +41 -0
  47. data/lib/generators/resty/templates/Editor.ui.xml~ +37 -0
  48. data/lib/generators/resty/templates/Event.java +30 -0
  49. data/lib/generators/resty/templates/Event.java~ +31 -0
  50. data/lib/generators/resty/templates/EventHandler.java +8 -0
  51. data/lib/generators/resty/templates/EventHandler.java~ +30 -0
  52. data/lib/generators/resty/templates/Model.java +144 -15
  53. data/lib/generators/resty/templates/Model.java~ +23 -0
  54. data/lib/generators/resty/templates/Place.java +1 -1
  55. data/lib/generators/resty/templates/Place.java~ +21 -0
  56. data/lib/generators/resty/templates/PlaceTokenizer.java +1 -1
  57. data/lib/generators/resty/templates/PlaceTokenizer.java~ +19 -0
  58. data/lib/generators/resty/templates/RestService.java~ +51 -0
  59. data/lib/generators/resty/templates/View.java +15 -4
  60. data/lib/generators/resty/templates/View.java~ +23 -0
  61. data/lib/generators/resty/templates/View.ui.xml +22 -38
  62. data/lib/generators/resty/templates/View.ui.xml~ +17 -0
  63. data/lib/generators/resty/templates/ViewImpl.java +88 -103
  64. data/lib/generators/resty/templates/ViewImpl.java~ +153 -0
  65. data/lib/resty/abstract_session.rb~ +59 -0
  66. data/lib/resty/child_path.rb~ +18 -0
  67. data/lib/resty/session.rb~ +6 -0
  68. metadata +56 -11
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
2
+ <ui:UiBinder
3
+ xmlns:ui="urn:ui:com.google.gwt.uibinder"
4
+ xmlns:g="urn:import:com.google.gwt.user.client.ui">
5
+
6
+ <ui:style>
7
+ </ui:style>
8
+
9
+ <g:SimplePanel>
10
+ <g:VerticalPanel>
11
+ <g:HorizontalPanel>
12
+ <g:Button ui:field="showButton">Show</g:Button>
13
+ </g:HorizontalPanel>
14
+ <g:HTML ui:field="modelsTable"/>
15
+ </g:VerticalPanel>
16
+ </g:SimplePanel>
17
+ </ui:UiBinder>
@@ -1,23 +1,20 @@
1
1
  package <%= views_package %>;
2
2
 
3
- <% unless options[:singleton] -%>
3
+ <% if !options[:singleton] || attributes.detect { |a| a.type == :belongs_to} -%>
4
4
  import java.util.List;
5
5
 
6
6
  <% end -%>
7
- <% if options[:timestamps] -%>
8
- import <%= gwt_rails_package %>.views.<% unless options[:singleton] -%>Identifyable<% end -%>TimestampedView;<% else -%><% unless options[:singleton] -%>
9
- import <%= gwt_rails_package %>.views.IdentifyableView;<% end -%><% end -%>
10
-
11
- <% unless options[:singleton] -%>
12
- import <%= gwt_rails_package %>.views.ModelButton;
7
+ import <%= editors_package %>.<%= class_name %>Editor;
8
+ <% for attribute in attributes -%>
9
+ <% if attribute.type == :belongs_to -%>
10
+ import <%= models_package %>.<%= attribute.name.classify %>;
11
+ <% end -%>
13
12
  <% end -%>
14
- import <%= gwt_rails_package %>.places.RestfulAction;
15
- import <%= gwt_rails_package %>.places.RestfulActionEnum;
16
-
17
13
  import <%= models_package %>.<%= class_name %>;
18
14
  import <%= places_package %>.<%= class_name %>Place;
19
15
 
20
16
  import com.google.gwt.core.client.GWT;
17
+ import com.google.gwt.editor.client.SimpleBeanEditorDriver;
21
18
  import com.google.gwt.event.dom.client.ClickEvent;
22
19
  <% unless options[:singleton] -%>
23
20
  import com.google.gwt.event.dom.client.ClickHandler;
@@ -26,88 +23,99 @@ import com.google.gwt.uibinder.client.UiBinder;
26
23
  import com.google.gwt.uibinder.client.UiField;
27
24
  import com.google.gwt.uibinder.client.UiHandler;
28
25
  import com.google.gwt.uibinder.client.UiTemplate;
29
- import com.google.gwt.user.client.ui.*;
26
+ import com.google.gwt.user.client.ui.Button;
27
+ import com.google.gwt.user.client.ui.Composite;
28
+ <% unless options[:singleton] -%>
29
+ import com.google.gwt.user.client.ui.FlexTable;
30
+ <% end -%>
31
+ import com.google.gwt.user.client.ui.Panel;
32
+ import com.google.gwt.user.client.ui.Widget;
30
33
  import com.google.inject.Singleton;
31
34
 
35
+ import <%= gwt_rails_package %>.places.RestfulAction;
36
+ import <%= gwt_rails_package %>.places.RestfulActionEnum;
37
+ <% unless options[:singleton] -%>
38
+ import <%= gwt_rails_package %>.views.ModelButton;
39
+ <% end -%>
40
+
32
41
  @Singleton
33
- public class <%= class_name %>ViewImpl extends <% if options[:timestamps] -%><% unless options[:singleton] -%>Identifyable<% end -%>TimestampedView<% else -%><% unless options[:singleton] -%>IdentifyableView<% else -%>Composite<% end -%><% end %>
34
- implements <%= class_name %>View {
42
+ public class <%= class_name %>ViewImpl extends Composite implements <%= class_name %>View {
35
43
 
36
44
  @UiTemplate("<%= class_name %>View.ui.xml")
37
- interface <%= class_name %>ViewUiBinder extends UiBinder<Widget, <%= class_name %>ViewImpl> {}
45
+ interface Binder extends UiBinder<Widget, <%= class_name %>ViewImpl> {}
38
46
 
39
- private static <%= class_name %>ViewUiBinder uiBinder = GWT.create(<%= class_name %>ViewUiBinder.class);
47
+ private static Binder BINDER = GWT.create(Binder.class);
48
+
49
+ interface EditorDriver extends SimpleBeanEditorDriver<<%= class_name %>, <%= class_name %>Editor> {}
50
+
51
+ private final EditorDriver editorDriver = GWT.create(EditorDriver.class);
40
52
 
41
53
  <% unless options[:readonly] -%>
42
54
  <% unless options[:singleton] -%>
43
- @UiField
44
- Button newButton;
45
-
46
- @UiField
47
- Button createButton;
48
- <% end -%>
49
- @UiField
50
- Button editButton;
51
-
52
- @UiField
53
- Button saveButton;
54
- <% unless options[:singleton] -%>
55
- @UiField
56
- Button deleteButton;
55
+ @UiField Button newButton;
56
+ <% end -%>
57
+ @UiField Button editButton;
58
+ <% end -%>
59
+ @UiField Button showButton;
57
60
 
61
+ <% unless options[:readonly] -%>
62
+ <% unless options[:singleton] -%>
63
+ @UiField Button createButton;
58
64
  <% end -%>
65
+ @UiField Button saveButton;
66
+ <% unless options[:singleton] -%>
67
+ @UiField Button deleteButton;
59
68
  <% end -%>
60
- <% for attribute in attributes -%>
61
- <% if attribute.type == :has_one -%>
62
- // TODO <%= attribute.name.camelcase %> <%= attribute.name %>;
63
- <% elsif attribute.type == :has_many -%>
64
- // TODO public java.util.List<<%= attribute.name.camelcase %>> <%= attribute.name %>;
65
- <% else -%>
66
- @UiField
67
- TextBox <%= attribute.name.camelcase.sub(/^(.)/){ $1.downcase } %>;
68
69
  <% end -%>
69
70
 
71
+ @UiField Panel model;
72
+ <% unless options[:singleton] -%>
73
+ @UiField FlexTable list;
70
74
  <% end -%>
71
- <% unless options[:singleton] -%>
72
- @UiField
73
- Panel form;
74
75
 
75
- @UiField
76
- FlexTable list;
77
- <% end -%>
76
+ @UiField <%= class_name %>Editor editor;
78
77
 
79
78
  private Presenter presenter;
80
79
 
81
80
  public <%= class_name %>ViewImpl() {
82
- initWidget(uiBinder.createAndBindUi(this));
81
+ initWidget(BINDER.createAndBindUi(this));
82
+ editorDriver.initialize(editor);
83
83
  }
84
- <% unless options[:readonly] %>
84
+ <% unless options[:readonly] -%>
85
85
  <% unless options[:singleton] -%>
86
+
86
87
  @UiHandler("newButton")
87
88
  void onClickNew(ClickEvent e) {
88
89
  presenter.goTo(new <%= class_name %>Place(RestfulActionEnum.NEW));
89
90
  }
91
+ <% end -%>
90
92
 
91
- @UiHandler("createButton")
92
- void onClickCreate(ClickEvent e) {
93
- presenter.create();
93
+ @UiHandler("showButton")
94
+ void onClickShow(ClickEvent e) {
95
+ presenter.goTo(new <%= class_name %>Place(<% unless options[:singleton] -%>editor.id.getValue(), <% end -%>RestfulActionEnum.SHOW));
94
96
  }
95
97
 
96
- <% end -%>
97
98
  @UiHandler("editButton")
98
99
  void onClickEdit(ClickEvent e) {
99
- presenter.goTo(new <%= class_name %>Place(<% unless options[:singleton] -%>id.getValue(), <% end -%>RestfulActionEnum.EDIT));
100
+ presenter.goTo(new <%= class_name %>Place(<% unless options[:singleton] -%>editor.id.getValue(), <% end -%>RestfulActionEnum.EDIT));
100
101
  }
102
+ <% unless options[:singleton] -%>
103
+
104
+ @UiHandler("createButton")
105
+ void onClickCreate(ClickEvent e) {
106
+ presenter.create();
107
+ }
108
+ <% end -%>
101
109
 
102
110
  @UiHandler("saveButton")
103
111
  void onClickSave(ClickEvent e) {
104
112
  presenter.save();
105
113
  }
106
-
107
114
  <% unless options[:singleton] -%>
115
+
108
116
  @UiHandler("deleteButton")
109
117
  void onClickDelete(ClickEvent e) {
110
- presenter.delete(retrieve<%= class_name %>());
118
+ presenter.delete(flush());
111
119
  }
112
120
 
113
121
  <% end -%>
@@ -116,22 +124,16 @@ public class <%= class_name %>ViewImpl extends <% if options[:timestamps] -%><%
116
124
  this.presenter = presenter;
117
125
  }
118
126
 
119
- public void reset(<%= class_name %> model) {
120
- <% if options[:singleton] && options[:timestamps] -%>
121
- resetSignature(model.createdAt, model.updatedAt);
122
- <% else -%>
123
- <% if options[:timestamps] %>
124
- resetSignature(model.id, model.createdAt, model.updatedAt);
125
- <% else -%>
126
- resetSignature(model.id);
127
- <% end -%>
128
- <% end -%>
129
- <% for attribute in attributes -%>
130
- <% if attribute.type != :has_one && attribute.type != :has_many -%>
131
- <% name = attribute.name.camelcase.sub(/^(.)/){ $1.downcase } -%>
132
- <%= name %>.setText(model.<%= name %><% if type_conversion_map[attribute.type] -%> + ""<% end -%>);
133
- <% end -%>
134
- <% end -%>
127
+ public void edit(<%= class_name %> model) {
128
+ this.editorDriver.edit(model);
129
+ }
130
+
131
+ public <%= class_name %> flush() {
132
+ return editorDriver.flush();
133
+ }
134
+
135
+ public void setEnabled(boolean enabled) {
136
+ editor.setEnabled(enabled);
135
137
  }
136
138
 
137
139
  public void reset(RestfulAction action) {
@@ -139,13 +141,15 @@ public class <%= class_name %>ViewImpl extends <% if options[:timestamps] -%><%
139
141
  editButton.setVisible(action.name().equals(RestfulActionEnum.SHOW.name()) ||
140
142
  action.name().equals(RestfulActionEnum.INDEX.name()));
141
143
  saveButton.setVisible(action.name().equals(RestfulActionEnum.EDIT.name()));
144
+ showButton.setVisible(action.name().equals(RestfulActionEnum.EDIT.name()));
142
145
  setEnabled(!action.viewOnly());
143
146
  <% else -%>
144
147
  newButton.setVisible(!action.name().equals(RestfulActionEnum.NEW.name()));
145
148
  if(action.name().equals(RestfulActionEnum.INDEX.name())){
146
149
  editButton.setVisible(false);
150
+ showButton.setVisible(false);
147
151
  list.setVisible(true);
148
- form.setVisible(false);
152
+ model.setVisible(false);
149
153
  }
150
154
  else {
151
155
  <% if options[:readonly] -%>
@@ -153,42 +157,14 @@ public class <%= class_name %>ViewImpl extends <% if options[:timestamps] -%><%
153
157
  <% else -%>
154
158
  createButton.setVisible(action.name().equals(RestfulActionEnum.NEW.name()));
155
159
  editButton.setVisible(action.name().equals(RestfulActionEnum.SHOW.name()));
160
+ showButton.setVisible(action.name().equals(RestfulActionEnum.EDIT.name()));
156
161
  saveButton.setVisible(action.name().equals(RestfulActionEnum.EDIT.name()));
157
162
  deleteButton.setVisible(action.name().equals(RestfulActionEnum.EDIT.name()));
158
163
  <% end -%>
159
164
  setEnabled(!action.viewOnly());
160
165
  list.setVisible(false);
161
- form.setVisible(true);
166
+ model.setVisible(true);
162
167
  }
163
- <% end -%>
164
- }
165
-
166
- public <%= class_name %> retrieve<%= class_name %>() {
167
- <%= class_name %> model = new <%= class_name %>();
168
- <% unless options[:singleton] -%>
169
- model.id = id.getValue() == null ? 0 : id.getValue();
170
- <% end -%>
171
- <% if options[:timestamps] %>
172
- model.createdAt = createdAt.getValue();
173
- model.updatedAt = updatedAt.getValue();
174
- <% end -%>
175
-
176
- <% for attribute in attributes -%>
177
- <% if attribute.type != :has_one && attribute.type != :has_many -%>
178
- <% name = attribute.name.camelcase.sub(/^(.)/){ $1.downcase } -%>
179
- model.<%= name %> = <% if (conv = type_conversion_map[attribute.type]).nil? -%><%= name %>.getText()<% else -%><%= conv %>(<%= name %>.getText())<% end -%>;
180
- <% end -%>
181
-
182
- <% end -%>
183
- return model;
184
- }
185
-
186
- public void setEnabled(boolean enabled) {
187
- <% for attribute in attributes -%>
188
- <% if attribute.type != :has_one && attribute.type != :has_many -%>
189
- <% name = attribute.name.camelcase.sub(/^(.)/){ $1.downcase } -%>
190
- <%= name %>.setEnabled(enabled);
191
- <% end -%>
192
168
  <% end -%>
193
169
  }
194
170
  <% unless options[:singleton] -%>
@@ -229,11 +205,11 @@ public class <%= class_name %>ViewImpl extends <% if options[:timestamps] -%><%
229
205
  }
230
206
 
231
207
  private void setRow(int row, <%= class_name %> model) {
232
- list.setText(row, 0, model.id + "");
208
+ list.setText(row, 0, model.getId() + "");
233
209
  <% attributes.each_with_index do |attribute, index| -%>
234
210
  <% if attribute.type != :has_one && attribute.type != :has_many -%>
235
211
  <% name = attribute.name.camelcase.sub(/^(.)/){ $1.downcase } -%>
236
- list.setText(row, <%= index + 1 %>, model.<%= name %> + "");
212
+ list.setText(row, <%= index + 1 %>, model.get<%= name.camelcase %>()<%= attribute.type == :has_one || attribute.type == :belongs_to ? ' == null ? "-" : model.get' + name.camelcase + '().toDisplay()' : ' + ""' %>);
237
213
  <% end -%>
238
214
 
239
215
  <% end -%>
@@ -243,7 +219,7 @@ public class <%= class_name %>ViewImpl extends <% if options[:timestamps] -%><%
243
219
  }
244
220
 
245
221
  public void updateInList(<%= class_name %> model) {
246
- String id = model.id + "";
222
+ String id = model.getId() + "";
247
223
  for(int i = 0; i < list.getRowCount(); i++){
248
224
  if(list.getText(i, 0).equals(id)){
249
225
  setRow(i, model);
@@ -253,7 +229,7 @@ public class <%= class_name %>ViewImpl extends <% if options[:timestamps] -%><%
253
229
  }
254
230
 
255
231
  public void removeFromList(<%= class_name %> model) {
256
- String id = model.id + "";
232
+ String id = model.getId() + "";
257
233
  for(int i = 0; i < list.getRowCount(); i++){
258
234
  if(list.getText(i, 0).equals(id)){
259
235
  list.removeRow(i);
@@ -266,4 +242,13 @@ public class <%= class_name %>ViewImpl extends <% if options[:timestamps] -%><%
266
242
  setRow(list.getRowCount(), model);
267
243
  }
268
244
  <% end -%>
245
+ <% for attribute in attributes -%>
246
+ <% if attribute.type == :belongs_to -%>
247
+ <% clazz = attribute.name.classify -%>
248
+
249
+ public void reset<%= clazz.to_s.pluralize %>(List<<%= clazz %>> list){
250
+ editor.reset<%= clazz.to_s.pluralize %>(list);
251
+ }
252
+ <% end -%>
253
+ <% end -%>
269
254
  }
@@ -0,0 +1,153 @@
1
+ package <%= views_package %>;
2
+
3
+ import java.util.List;
4
+
5
+ import <%= gwt_rails_package %>.ColumnDefinition;
6
+ import <%= gwt_rails_package %>.RestfulActionEnum;
7
+
8
+ import <%= models_package %>.<%= class_name %>;
9
+ import <%= places_package %>.<%= class_name %>Place;
10
+
11
+ import com.google.gwt.core.client.GWT;
12
+ import com.google.gwt.dom.client.Document;
13
+ import com.google.gwt.dom.client.Element;
14
+ import com.google.gwt.dom.client.EventTarget;
15
+ import com.google.gwt.dom.client.Node;
16
+ import com.google.gwt.dom.client.TableCellElement;
17
+ import com.google.gwt.dom.client.TableElement;
18
+ import com.google.gwt.dom.client.TableRowElement;
19
+ import com.google.gwt.dom.client.TableSectionElement;
20
+ import com.google.gwt.event.dom.client.ClickEvent;
21
+ import com.google.gwt.uibinder.client.UiBinder;
22
+ import com.google.gwt.uibinder.client.UiField;
23
+ import com.google.gwt.uibinder.client.UiHandler;
24
+ import com.google.gwt.uibinder.client.UiTemplate;
25
+ import com.google.gwt.user.client.Event;
26
+ import com.google.gwt.user.client.ui.Button;
27
+ import com.google.gwt.user.client.ui.Composite;
28
+ import com.google.gwt.user.client.ui.HTML;
29
+ import com.google.gwt.user.client.ui.TextBox;
30
+ import com.google.gwt.user.client.ui.Widget;
31
+ import com.google.inject.Singleton;
32
+
33
+ @Singleton
34
+ public class <%= class_name %>ViewImpl extends Composite
35
+ implements <%= class_name %>View {
36
+
37
+ @UiTemplate("<%= class_name %>View.ui.xml")
38
+ interface <%= class_name %>ViewUiBinder extends UiBinder<Widget, <%= class_name %>ViewImpl> {}
39
+
40
+ private static <%= class_name %>ViewUiBinder uiBinder = GWT.create(<%= class_name %>ViewUiBinder.class);
41
+
42
+ @UiField
43
+ Button showButton;
44
+ // @UiField
45
+ // TextBox login;
46
+
47
+ @UiField
48
+ HTML modelsTable;
49
+
50
+ private Presenter presenter;
51
+
52
+ private List<ColumnDefinition<<%= class_name %>>> columnDefinitions = new <%= class_name.pluralize %>ColumnDefinitionsImpl();
53
+
54
+ private List<<%= class_name %>> models;
55
+
56
+ public <%= class_name %>ViewImpl() {
57
+ initWidget(uiBinder.createAndBindUi(this));
58
+ }
59
+
60
+ @UiHandler("showButton")
61
+ void onClickEdit(ClickEvent e) {
62
+ presenter.goTo(new <%= class_name %>Place(RestfulActionEnum.EDIT));
63
+ }
64
+
65
+ public void setPresenter(Presenter presenter) {
66
+ this.presenter = presenter;
67
+ }
68
+
69
+ public void reset(<%= class_name %> model) {
70
+ // TODO
71
+ }
72
+
73
+ public void reset(List<<%= class_name %>> models) {
74
+ this.models = models;
75
+
76
+ TableElement table = Document.get().createTableElement();
77
+ TableSectionElement tbody;
78
+ table.appendChild(tbody = Document.get().createTBodyElement());
79
+
80
+ for (int i = 0; i < models.size(); ++i) {
81
+ TableRowElement row = tbody.insertRow(-1);
82
+ <%= class_name %> t = models.get(i);
83
+
84
+ for (int j = 0; j < columnDefinitions.size(); ++j) {
85
+ TableCellElement cell = row.insertCell(-1);
86
+ StringBuilder sb = new StringBuilder();
87
+ columnDefinitions.get(j).render(t, sb);
88
+ cell.setInnerHTML(sb.toString());
89
+
90
+ // TODO: Really total hack! There's gotta be a better way...
91
+ Element child = cell.getFirstChildElement();
92
+ if (child != null) {
93
+ Event.sinkEvents(child, Event.ONFOCUS | Event.ONBLUR);
94
+ }
95
+ }
96
+ }
97
+
98
+ modelsTable.setHTML(table.getInnerHTML());
99
+ }
100
+
101
+ private TableCellElement findNearestParentCell(Node node) {
102
+ while ((node != null)) {
103
+ if (Element.is(node)) {
104
+ Element elem = Element.as(node);
105
+
106
+ String tagName = elem.getTagName();
107
+ if ("td".equalsIgnoreCase(tagName) || "th".equalsIgnoreCase(tagName)) {
108
+ return elem.cast();
109
+ }
110
+ }
111
+ node = node.getParentNode();
112
+ }
113
+ return null;
114
+ }
115
+
116
+
117
+ @UiHandler("modelsTable")
118
+ void onTableClicked(ClickEvent event) {
119
+ if (presenter != null) {
120
+ EventTarget target = event.getNativeEvent().getEventTarget();
121
+ Node node = Node.as(target);
122
+ TableCellElement cell = findNearestParentCell(node);
123
+ if (cell == null) {
124
+ return;
125
+ }
126
+
127
+ TableRowElement tr = TableRowElement.as(cell.getParentElement());
128
+ int row = tr.getSectionRowIndex();
129
+
130
+ if (cell != null) {
131
+ if (shouldFireClickEvent(cell)) {
132
+ presenter.onItemClicked(models.get(row));
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ private boolean shouldFireClickEvent(TableCellElement cell) {
139
+ boolean shouldFireClickEvent = false;
140
+
141
+ if (cell != null) {
142
+ ColumnDefinition<<%= class_name %>> columnDefinition =
143
+ columnDefinitions.get(cell.getCellIndex());
144
+
145
+ if (columnDefinition != null) {
146
+ shouldFireClickEvent = columnDefinition.isClickable();
147
+ }
148
+ }
149
+
150
+ return shouldFireClickEvent;
151
+ }
152
+
153
+ }