BrightSide Workbench Full Report + Source Code
EditCProfileControl.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2021 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.contacts.profile;
20 
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Date;
26 import java.util.List;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29 import java.util.stream.Collectors;
30 import org.turro.string.Strings;
31 import org.apache.commons.mail.EmailException;
32 import org.turro.action.Actions;
33 import org.turro.action.Contacts;
34 import org.turro.action.PushSenders;
35 import org.turro.collections.KeyValueMap;
36 import org.turro.contacts.Comment;
37 import org.turro.contacts.Contact;
38 import org.turro.contacts.comment.AboutWrapper;
39 import org.turro.contacts.db.ContactsPU;
40 import org.turro.contacts.form.ContactWrapper;
41 import org.turro.elephant.TemplateControl;
42 import org.turro.elephant.context.Application;
43 import org.turro.elephant.context.ElephantContext;
44 import org.turro.elephant.entities.db.Skill;
45 import org.turro.elephant.entities.db.SkillType;
46 import org.turro.elephant.security.IUser;
47 import org.turro.file.util.FileAttach;
48 import org.turro.i18n.I_;
49 import org.turro.mail.sender.MailPool;
50 import org.turro.plugin.contacts.IContact;
51 import org.turro.security.SecurityGroup;
52 import org.turro.skills.SkillRoot;
53 import org.turro.skills.Skills;
54 import org.turro.skills.SkillsChosenbox;
55 import org.turro.upload.Medias;
56 import org.turro.util.IdGenerator;
57 import org.zkoss.image.AImage;
58 import org.zkoss.util.media.Media;
59 import org.zkoss.zk.ui.event.Event;
60 import org.zkoss.zk.ui.event.Events;
61 import org.zkoss.zk.ui.event.InputEvent;
62 import org.zkoss.zk.ui.event.UploadEvent;
63 import org.zkoss.zk.ui.select.annotation.Listen;
64 import org.zkoss.zk.ui.select.annotation.Wire;
65 import org.zkoss.zul.Image;
66 import org.zkoss.zul.Tab;
67 import org.zkoss.zul.Tabpanel;
68 import org.zkoss.zul.Tabpanels;
69 import org.zkoss.zul.Tabs;
70 import org.zkoss.zul.Textbox;
71 
76 public class EditCProfileControl extends TemplateControl {
77 
78  private IContact contact;
79  private String path;
80  private List<String> langs;
81  private List<AboutWrapper> model;
82 
83  @Wire("#name") private Textbox name;
84  @Wire("#web") private Textbox web;
85  @Wire("#trade") private Textbox trade;
86  @Wire("#face") private Image face;
87  @Wire("#tabs") private Tabs tabs;
88  @Wire("#tabpanels") private Tabpanels tabpanels;
89  @Wire("#sector") private SkillsChosenbox sector;
90  @Wire("#specialty") private SkillsChosenbox specialty;
91 
92 
93  @Listen("onChange=#web")
94  public void onWeb() {
95  contact.setConnector(Profile.WEB, web.getValue());
96  }
97 
98  @Listen("onChange=#trade")
99  public void onTrade() {
100  contact.setConnector(IUser.CONNECTOR_TRADE, trade.getValue());
101  }
102 
103  @Listen("onUpload = #uploadface")
104  public void onEvent(UploadEvent t) throws Exception {
105  FileAttach fileAttach = new FileAttach(ContactsPU.getObjectPath(contact.getContact()));
106  File newFile = new File(ElephantContext.getRealPath(fileAttach.getPublishable() + "/profile/face.png"));
107  if(!newFile.getParentFile().exists()) {
108  newFile.getParentFile().mkdirs();
109  }
110  Media media = t.getMedia();
111  if(media != null) {
112  Medias.toFile(media, newFile, Medias.scaling(600));
113  }
114  if(newFile.exists()) {
115  try {
116  face.setContent(new AImage(newFile.getAbsolutePath()));
117  } catch (IOException ex) {
118  Logger.getLogger(EditProfileControl.class.getName()).log(Level.SEVERE, null, ex);
119  }
120  } else {
121  face.setSrc(null);
122  }
123  }
124 
125  @Listen("onSelect=#sector")
126  public void onSector() {
127  String entityPath = ContactsPU.getObjectPath(contact.getContact());
128  Skills.setSkillsFor(entityPath, sector.getObjectValues()
129  .stream().map(s -> s.getFor(entityPath)).collect(Collectors.toSet()),
131  }
132 
133  @Listen("onSelect=#specialty")
134  public void onSpecialty() {
135  String entityPath = ContactsPU.getObjectPath(contact.getContact());
136  Skills.setSkillsFor(entityPath, specialty.getObjectValues()
137  .stream().map(s -> s.getFor(entityPath)).collect(Collectors.toSet()),
139  }
140 
141  @Listen("onSearch=#sector")
142  public void onNewSector(InputEvent event) {
143  String value = event.getValue();
144  String entityPath = ContactsPU.getObjectPath(contact.getContact());
145  if(!Strings.isBlank(value)) {
146  Skill skill = new Skill();
147  skill.setSkill(value);
148  skill.setEntityPath(entityPath);
150  Skills.addSkillFor(entityPath, skill);
151  sector.addToModel(new SkillRoot(skill));
152  }
153  }
154 
155  @Listen("onSearch=#specialty")
156  public void onNewSpecialty(InputEvent event) {
157  String value = event.getValue();
158  String entityPath = ContactsPU.getObjectPath(contact.getContact());
159  if(!Strings.isBlank(value)) {
160  Skill skill = new Skill();
161  skill.setSkill(value);
162  skill.setEntityPath(entityPath);
164  Skills.addSkillFor(entityPath, skill);
165  specialty.addToModel(new SkillRoot(skill));
166  }
167  }
168 
169  @Listen("onClick=#save")
170  public void onSave() {
171  if(contact.isValid()) {
172  Contact c = (Contact) contact.getContact();
173  if(model != null) {
174  for(AboutWrapper wrapper : model) {
175  if(wrapper.isNewComment() && !wrapper.isEmpty()) {
176  Comment comment = wrapper.getComment();
177  comment.setContact(c);
178  comment.setModification(new Date());
179  c.getComments().add(comment);
180  }
181  }
182  }
183  new ContactWrapper(c).save();
185  sendNotification((Contact) contact.getContact());
186  }
187  }
188 
189  @Listen("onClick=#cancel")
190  public void onCancel() {
192  }
193 
194  public String getPath() {
195  return path;
196  }
197 
198  public void setPath(String path) {
199  this.path = path;
200  }
201 
202  public List<String> getLangModel() {
203  if(langs == null) {
204  langs = new ArrayList<>();
205  langs.add("#"); // default
206  langs.addAll(Arrays.asList(ElephantContext.getSiteLocales().split(" *, *")));
207  }
208  return langs;
209  }
210 
211  private String chooseLabel(String lang) {
212  if("#".equals(lang)) {
213  return I_.get("Default");
214  } else {
215  return I_.byKey(lang);
216  }
217  }
218 
219  public void setAboutModel() {
220  if(model == null) {
221  Contact c = (Contact) contact.getContact();
222  model = new ArrayList<>();
223  getLangModel().forEach((lang) -> {
224  boolean done = false;
225  for(Comment comment : c.getComments()) {
226  if(comment.getComment().startsWith("#cv" + lang)) {
227  AboutWrapper wrapper = new AboutWrapper(lang, chooseLabel(lang), comment);
228  model.add(wrapper);
229  done = true;
230  }
231  }
232  if (!done) {
233  AboutWrapper wrapper = new AboutWrapper(lang, chooseLabel(lang), new Comment());
234  model.add(wrapper);
235  }
236  });
237  }
238  model.forEach(a -> {
239  Tab tab = new Tab(a.getLangLabel());
240  tabs.appendChild(tab);
241  Tabpanel tabpanel = new Tabpanel();
242  tabpanels.appendChild(tabpanel);
243  Textbox about = new Textbox();
244  about.setMultiline(true);
245  about.setRows(15);
246  about.setTabbable(true);
247  about.setStyle("-moz-tab-size:4;-o-tab-size:4;tab-size:4;width:100%;height:100%;");
248  about.setValue(a.getCommentString());
249  about.addEventListener(Events.ON_CHANGE, (Event event) -> {
250  a.setCommentString(about.getValue());
251  });
252  tabpanel.appendChild(about);
253  });
254  }
255 
256  @Override
257  protected void doFinally() {
258  super.doFinally();
260  if(kvm != null && kvm.containsKey("contact")) {
261  contact = Contacts.getContactById(kvm.get("contact"));
262  }
263  initComponents();
264  }
265 
266  private void initComponents() {
267  if(contact != null && contact.isValid()) {
268  name.setValue(contact.getName());
269  name.setReadonly(true);
270  web.setValue(contact.getConnector(Profile.WEB));
271  trade.setValue(contact.getConnector(IUser.CONNECTOR_TRADE));
272  FileAttach fileAttach = new FileAttach(ContactsPU.getObjectPath(contact.getContact()));
273  String faceFile = fileAttach.getPublicFile("/profile/face.png", false);
274  if(!Strings.isBlank(faceFile)) {
275  face.setSrc(faceFile + "?" + IdGenerator.generate());
276  }
277  setAboutModel();
278  String entityPath = ContactsPU.getObjectPath(contact.getContact());
279  sector.setObjectValues(Skills.getSkillsAsRootFrom(entityPath, SkillType.SKILL_SECTOR));
280  specialty.setObjectValues(Skills.getSkillsAsRootFrom(entityPath, SkillType.SKILL_SPECIALTY));
281  } else {
282  Application.getApplication().navigateBack();
283  }
284  }
285 
286  private void sendNotification(Contact c) {
287  try {
288  FileAttach fileAttach = new FileAttach(ContactsPU.getObjectPath(c));
289  String faceFile = fileAttach.getPublicFile("/profile/face.png", false);
290  new MailPool()
291  .addAdministrators()
292  .addBySyndication(SecurityGroup.CONTACTS_ADMIN)
293  .setRoot("/about")
294  .put("about", c)
295  .put("model", model)
296  .put("face", faceFile)
297  .sendTemplate("change-notification",
298  I_.get("Modified") + ": " + I_.get("About"));
299  } catch (EmailException ex) {
300  Logger.getLogger(EditCProfileControl.class.getName()).log(Level.SEVERE, null, ex);
301  }
302  PushSenders.getPool()
303  .addAdministrators()
304  .addBySyndication(SecurityGroup.CONTACTS_ADMIN)
305  .send(I_.get("Modified") + ": " + I_.get("About"), c.getName());
306  }
307 
308 }
static KeyValueMap getRightNowAction(IConstructor constructor)
Definition: Actions.java:341
static IContact getContactById(String id)
Definition: Contacts.java:72
void setContact(Contact contact)
Definition: Comment.java:93
void setModification(Date modification)
Definition: Comment.java:77
Set< Comment > getComments()
Definition: Contact.java:415
static String getObjectPath(Object object)
Definition: ContactsPU.java:68
void setSkill(String skill)
Definition: Skill.java:47
void setType(SkillType type)
Definition: Skill.java:63
void setEntityPath(String entityPath)
Definition: Skill.java:55
String getPublicFile(String file)
Definition: FileAttach.java:59
static String byKey(String key)
Definition: I_.java:83
static String get(String msg)
Definition: I_.java:41
void addToModel(SkillRoot value)
static void setSkillsFor(String entityPath, Set< Skill > skills, SkillType... types)
Definition: Skills.java:91
static void addSkillFor(String entityPath, Skill skill)
Definition: Skills.java:85
static void toFile(Media media, File file)
Definition: Medias.java:66
static Consumer< File > scaling(double scale)
Definition: Medias.java:102
static final String CONNECTOR_TRADE
Definition: IUser.java:28
void setConnector(String id, String value)