BrightSide Workbench Full Report + Source Code
EntityComposer.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2012 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.jpa.composer;
20 
21 import org.turro.elephant.util.Components;
22 import org.turro.elephant.util.Images;
23 import org.turro.elephant.util.Messages;
24 import org.turro.i18n.I_;
25 import org.turro.jpa.entity.DaoEntity;
26 import org.turro.jpa.entity.IDaoEntity;
27 import org.turro.json.Jsons;
28 import org.turro.reflection.XMLSerializer;
29 import org.turro.reflection.stub.Stubs;
30 import org.turro.zul.frame.Framework;
31 import org.zkoss.zk.ui.Component;
32 import org.zkoss.zk.ui.Executions;
33 import org.zkoss.zk.ui.event.Event;
34 import org.zkoss.zk.ui.event.EventListener;
35 import org.zkoss.zk.ui.event.Events;
36 import org.zkoss.zk.ui.select.SelectorComposer;
37 import org.zkoss.zk.ui.select.annotation.Listen;
38 import org.zkoss.zk.ui.select.annotation.Wire;
39 import org.zkoss.zul.Tab;
40 import org.zkoss.zul.Tabpanel;
41 import org.zkoss.zul.Toolbarbutton;
42 
49 public abstract class EntityComposer<E, ID> extends SelectorComposer<Component> {
50 
51  private String entityXML, entityJSON;
52  protected E entity;
53  protected DaoEntity wrapper;
54 
55  @Wire("#save")
56  private Toolbarbutton save;
57 
58  @Wire("#delete")
59  private Toolbarbutton delete;
60 
61  @Listen("onChange = *; onSelect = *; onCheck = *")
62  public final void onChange(Event event) {
63  if(!(event.getTarget() instanceof Tab)) {
64  save.setDisabled(!(wrapper.canSave() && (hasChanged() || shouldBeSaved())) || !inSaveRole());
65  doOnChange();
66  }
67  }
68 
69  @Listen("onClick = #save")
70  public final void onSave() {
71  doOnSave();
72  }
73 
74  @Listen("onClick = #delete")
75  public final void onDelete() {
76  doOnDelete();
77  }
78 
79  public Object getEntity() {
80  return entity;
81  }
82 
83  public Object getWrapper() {
84  return wrapper;
85  }
86 
87  @Override
88  public void doBeforeComposeChildren(Component comp) throws Exception {
89  entity = null;
90  retrieveEntity();
91  comp.setAttribute(getAttributeName(), entity);
92  wrapper = getWrapperInstance(comp);
93  comp.setAttribute("wrapper", wrapper);
94  super.doBeforeComposeChildren(comp);
95  }
96 
97  @Override
98  public void doFinally() throws Exception {
99  super.doFinally();
100  save.setDisabled(!shouldBeSaved());
101  save.setLabel(I_.get("Save"));
102  save.setImage(Images.getImage("save"));
103  delete.setDisabled(!wrapper.canDelete() || !inDeleteRole());
104  delete.setLabel(I_.get("Delete"));
105  delete.setImage(Images.getImage("edit-delete"));
106  }
107 
108  @Override
109  public void doAfterCompose(Component comp) throws Exception {
110  super.doAfterCompose(comp);
111  interceptOnClose();
112  }
113 
114  protected abstract String getAttributeName();
115  protected abstract E getEntityInstance(ID id);
116  protected abstract DaoEntity getWrapperInstance(Component comp);
117  protected abstract boolean inSaveRole();
118  protected abstract boolean inDeleteRole();
119 
120  protected void doOnSave() {
121  if(beforeSave()) {
122  entity = (E) wrapper.save();
123  Framework.getCurrent().closeSelected();
124  afterSave();
125  }
126  }
127 
128  protected boolean beforeSave() {
129  return !((IDaoEntity) entity).isEmpty();
130  }
131 
132  protected void afterSave() {
133  // do nothing
134  }
135 
136  protected void doOnDelete() {
137  if(beforeDelete()) {
138  if(wrapper.delete()) {
139  Framework.getCurrent().closeSelected();
140  afterDelete();
141  }
142  }
143  }
144 
145  protected boolean beforeDelete() {
146  return true;
147  }
148 
149  protected void afterDelete() {
150  // do nothing
151  }
152 
153  protected void doOnChange() {
154  // do nothing
155  }
156 
157  protected boolean shouldBeSaved() {
158  return false;
159  }
160 
161  protected boolean hasChanged() {
162  return !Jsons.isEmpty(entityJSON) ? (!Jsons.equals(entityJSON, Stubs.json(entity))) :
163  (entityXML == null || (!entityXML.equals(new XMLSerializer(entity).data())));
164  }
165 
166  protected void retrieveEntity() {
167  Framework frame = Framework.getCurrent();
168  entity = (E) frame.getSelectedAttribute("tp_entity");
169  if(entity == null) {
170  if(Executions.getCurrent().getAttribute(getAttributeName() + "Generated") != null) {
171  entity = (E) Executions.getCurrent().getAttribute(getAttributeName() + "Generated");
172  Executions.getCurrent().removeAttribute(getAttributeName() + "Generated");
173  } else {
174  entity = (E) getEntityInstance((ID) frame.getDesktop().getAttribute(getAttributeName() + "Id"));
175  frame.getDesktop().removeAttribute(getAttributeName() + "Id");
176  }
177  frame.setSelectedAttribute("tp_entity", entity);
178  } else {
179  entity = (E) getEntityInstance((ID) DaoEntity.getEntityId(entity));
180  }
181  entityXML = new XMLSerializer(entity).data();
182  entityJSON = Stubs.json(entity);
183  }
184 
185  protected boolean canClose() {
186  return true;
187  }
188 
189  private void interceptOnClose() {
190  Tabpanel container = Components.from(getSelf().getPage()).parent(Tabpanel.class);
191  if(container != null) {
192  final Tab tab = container.getLinkedTab();
193  tab.addEventListener(9000, Events.ON_CLOSE, new EventListener<Event>() {
194  @Override
195  public void onEvent(final Event event) throws Exception {
196  if(!save.isDisabled()) {
197  if(canClose()) {
198  event.stopPropagation();
199  Messages.question().add("Close without saving?").show(() -> {
200  Framework.getCurrent().closeSelected();
201  });
202  }
203  }
204  }
205  });
206  }
207  }
208 
209 }