BrightSide Workbench Full Report + Source Code
IssueRelation.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2011 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 package org.turro.dossier.zul.relation;
19 
20 import java.util.List;
21 import java.util.Set;
22 import org.turro.collections.CollectionUtil;
23 import org.turro.command.Command;
24 import org.turro.command.Context;
25 import org.turro.dossier.db.DossierPU;
26 import org.turro.dossier.entity.Issue;
27 import org.turro.dossier.entity.IssuePredecessor;
28 import org.turro.dossier.entity.IssuePredecessorType;
29 import org.turro.dossier.issue.IssueWrapper;
30 import org.turro.elephant.util.Messages;
31 import org.turro.elephant.zkoss.Modal;
32 import org.turro.i18n.I_;
33 import org.turro.registry.ChangeCategory;
34 import org.turro.registry.Changes;
35 import org.turro.registry.UniqueString;
36 import org.zkoss.zk.ui.Component;
37 import org.zkoss.zk.ui.event.Event;
38 import org.zkoss.zk.ui.event.EventListener;
39 import org.zkoss.zk.ui.event.Events;
40 import org.zkoss.zul.Treecell;
41 import org.zkoss.zul.Treechildren;
42 import org.zkoss.zul.Treeitem;
43 import org.zkoss.zul.Treerow;
44 
49 public class IssueRelation extends Treeitem {
50 
51  private Treechildren children;
52  private final Issue issue;
53  private IssuePredecessor predecessor;
54 
55  public IssueRelation(IssuePredecessor predecessor, Issue issue) {
56  this.predecessor = predecessor;
57  this.issue = issue;
58  initLoadOnDemand();
59  addCells();
60  addChildrenSpace();
61  addTargets();
62  }
63 
64  public Issue getIssue() {
65  return issue;
66  }
67 
69  return predecessor;
70  }
71 
72  public List<IssueRelation> getRelatedChildren() {
73  return CollectionUtil.from(children.getChildren()).<List<IssueRelation>>cast();
74  }
75 
77  Component comp = getParent().getParent();
78  return (IssueRelation) (comp instanceof IssueRelation ? comp : null);
79  }
80 
81  public void reloadRelated() {
82  removeChild(children);
83  addChildrenSpace();
84  addTargets();
85  }
86 
87  public void reloadParent() {
88  if(getRelatedParent() == null) {
89  reloadTree();
90  } else {
92  }
93  }
94 
95  public void reloadTree() {
96  ((IssueRelationTree) getTree()).setIssue(((IssueRelationTree) getTree()).getIssue());
97  }
98 
99  public void doAddRelation(final Changes changes) throws InterruptedException {
100  final IssuePredecessor ip = new IssuePredecessor();
101  ip.setTarget(issue);
103  getDesktop().setAttribute("predecessor", ip);
104 
105  Modal.doModal("/WEB-INF/_zul/issue/relation.zul", new Command() {
106  @Override
107  public Object execute(Context context) {
108  if(checkRelation(ip)) {
109  predecessor = new DossierPU().saveObject(ip);
110  reloadTree();
111  if(changes != null) {
112  ChangeCategory cc = new ChangeCategory(3, I_.get("Relations"));
113  changes.addChange(new UniqueString(cc, "", "+" + getPredecessor().getFullDescription()));
114  }
115  }
116  return null;
117  }
118  });
119  }
120 
121  public void doEditRelation(final Changes changes) throws InterruptedException {
122  getDesktop().setAttribute("predecessor", predecessor);
123  Modal.doModal("/WEB-INF/_zul/issue/relation.zul", new Command() {
124  @Override
125  public Object execute(Context context) {
126  if(checkRelation(predecessor)) {
127  predecessor = new DossierPU().saveObject(predecessor);
128  reloadParent();
129  if(changes != null) {
130  ChangeCategory cc = new ChangeCategory(3, I_.get("Relations"));
131  changes.addChange(new UniqueString(cc, "", getPredecessor().getFullDescription()));
132  }
133  }
134  return null;
135  }
136  });
137  }
138 
139  public void doDeleteRelation() throws InterruptedException {
140  Messages.confirmDeletion().show(() -> {
141  new DossierPU().deleteObject(predecessor);
142  reloadTree();
143  });
144  }
145 
146  public boolean canDelete() {
147  return predecessor != null;
148  }
149 
150  public boolean canEdit() {
151  return predecessor != null;
152  }
153 
154  private void addChildrenSpace() {
155  children = new Treechildren();
156  appendChild(children);
157  }
158 
159  private void addCells() {
160  Treerow row = new Treerow();
161  appendChild(row);
162 
163  String src = null;
164  if(predecessor != null) {
165  if(predecessor.getType().equals(IssuePredecessorType.START_WHEN_STARTS)) {
166  src = "/_zul/images/start_starts.png";
167  } else {
168  src = "/_zul/images/start_ends.png";
169  }
170  }
171  row.appendChild(new Treecell("#" + issue.getId() + " " + issue.getDescription(), src));
172  row.appendChild(new Treecell(I_.byKey(issue.getStatus().toString())));
173  row.appendChild(new Treecell(new IssueWrapper(issue).getResponsibleString()));
174  }
175 
176  private void initLoadOnDemand() {
177  setOpen(false);
178  addEventListener(Events.ON_OPEN, new EventListener() {
179  @Override
180  public void onEvent(Event event) throws Exception {
181  if(isOpen()) {
182  addTargets();
183  }
184  }
185  });
186  }
187 
188  private void addTargets() {
189  if(children.getChildren().isEmpty()) {
190  Set<IssuePredecessor> ips = issue.getTargets();
191  for(IssuePredecessor ip : ips) {
192  children.appendChild(new IssueRelation(ip, ip.getTarget()));
193  }
194  }
195  }
196 
197  private boolean checkRelation(IssuePredecessor ip) {
198  if(ip.getSource() != null && ip.getTarget() != null) {
199  if(ip.getSource().getId().equals(ip.getTarget().getId())) {
200  return false;
201  }
202  if(!ip.getSource().getId().equals(issue.getId()) && followUp(ip.getSource())) {
203  return false;
204  }
205  if(!ip.getTarget().getId().equals(issue.getId()) && followDown(ip.getTarget())) {
206  return false;
207  }
208  return true;
209  }
210  return false;
211  }
212 
213  private boolean followUp(Issue source) {
214  for(IssuePredecessor ip : source.getSources()) {
215  if(ip.getSource().getId().equals(issue.getId())) {
216  return true;
217  } else {
218  followUp(ip.getSource());
219  }
220  }
221  return false;
222  }
223 
224  private boolean followDown(Issue target) {
225  for(IssuePredecessor ip : target.getTargets()) {
226  if(ip.getTarget().getId().equals(issue.getId())) {
227  return true;
228  } else {
229  followUp(ip.getTarget());
230  }
231  }
232  return false;
233  }
234 
235 }
void setType(IssuePredecessorType type)
Set< IssuePredecessor > getTargets()
Definition: Issue.java:279
IssueRelation(IssuePredecessor predecessor, Issue issue)
void doAddRelation(final Changes changes)
void doEditRelation(final Changes changes)
static Messages confirmDeletion()
Definition: Messages.java:87
static int doModal(String file)
Definition: Modal.java:38
static String get(String msg)
Definition: I_.java:41
void deleteObject(Object obj)
Definition: Dao.java:162