BrightSide Workbench Full Report + Source Code
FileFolder.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2015 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.file.zul.navigator;
20 
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27 import org.apache.commons.io.FileUtils;
28 import org.turro.attach.zul.FolderNameCombobox;
29 import org.turro.collections.CollectionUtil;
30 import org.turro.command.Command;
31 import org.turro.command.Context;
32 import org.turro.elephant.context.Application;
33 import org.turro.elephant.context.ElephantContext;
34 import org.turro.elephant.impl.util.StringParser;
35 import org.turro.elephant.util.Messages;
36 import org.turro.entities.Entities;
37 import org.turro.file.zul.control.FileResults;
38 import org.turro.i18n.I_;
39 import org.turro.plugin.attach.IAttachFolder;
40 import org.turro.upload.Medias;
41 import org.turro.zkoss.dialog.InputDialog;
42 import org.turro.zkoss.dialog.InputField;
43 import org.zkoss.lang.Strings;
44 import org.zkoss.util.media.Media;
45 import org.zkoss.zk.ui.HtmlBasedComponent;
46 import org.zkoss.zk.ui.event.DropEvent;
47 import org.zkoss.zk.ui.event.Event;
48 import org.zkoss.zk.ui.event.EventListener;
49 import org.zkoss.zk.ui.event.Events;
50 import org.zkoss.zk.ui.ext.AfterCompose;
51 import org.zkoss.zul.Treecell;
52 import org.zkoss.zul.Treechildren;
53 import org.zkoss.zul.Treeitem;
54 import org.zkoss.zul.Treerow;
55 
60 public class FileFolder extends Treeitem implements IAttachFolder, AfterCompose {
61 
62  private Application app = Application.getApplication();
63 
64  private Treechildren children;
65  private String label, realLabel;
66  private String path;
67  private boolean loadOnDemand;
68 
69  public FileFolder(String label, String path, boolean loadOnDemand) {
70  super();
71  this.label = label;
72  this.realLabel = label;
73  this.path = path;
74  this.loadOnDemand = loadOnDemand;
75  this.setTooltiptext(label);
76  }
77 
78  public FileFolder(String label, Object value) {
79  throw new UnsupportedOperationException("Do not use");
80  }
81 
82  public FileFolder(String label) {
83  throw new UnsupportedOperationException("Do not use");
84  }
85 
86  public FileFolder() {
87  throw new UnsupportedOperationException("Do not use");
88  }
89 
90  @Override
91  public FileTree getTree() {
92  return (FileTree) super.getTree();
93  }
94 
95  public void addMedias(Media[] medias) throws InterruptedException, IOException {
96  if(medias == null || medias.length == 0) return;
97  fillFolder();
98  setOpen(true);
99  for(Media media : medias) {
100  Medias.toFolder(media, getRealFolder());
101  }
102  reloadContents();
103  }
104 
105  public void doAddFolder() throws InterruptedException {
107  getPage(),
108  I_.get("Folder"),
109  new InputField[] {
110  new InputField("Name", "", null, 0) {
111  @Override
112  protected HtmlBasedComponent createEditor() {
113  return new FolderNameCombobox(FileFolder.this);
114  }
115  }
116  }, new Command() {
117  @Override
118  public Object execute(Context context) {
119  InputField[] fields = (InputField[]) context.get("fields");
120  if(fields.length > 0) {
121  for(InputField f : fields) {
122  if("Name".equals(f.getLabel())) {
123  fillFolder();
124  FileFolder af = FileFolder.this;
125  for(String s : ((String) f.getValue()).split("\\/")) {
126  if(!Strings.isBlank(s)) {
127  af.setOpen(true);
128  af = af.addFolder(s, af.getPath() + "/" + s);
129  }
130  }
131  }
132  }
133  }
134  return null;
135  }
136  });
137  }
138 
139  public FileFolder addFolder(String label, String path) {
140  FileFolder af = new FileFolder(label, path, loadOnDemand);
141  if(children == null) {
142  children = new Treechildren();
143  appendChild(children);
144  }
145  children.appendChild(af);
146  af.afterCompose();
147  af.doProcessors();
148  return af;
149  }
150 
151  public void showContents() {
152  fillFolder();
153  setOpen(true);
154  }
155 
156  public void reloadContents() {
157  if(children != null) {
158  children.getChildren().clear();
159  showContents();
160  }
161  }
162 
163  private void addCells() {
164  Treerow row = new Treerow();
165  row.setDroppable("true");
166  row.addEventListener(Events.ON_DROP, new EventListener() {
167  @Override
168  public void onEvent(Event event) throws Exception {
169  final DropEvent dp = (DropEvent) event;
170  if(dp.getDragged() instanceof FileRow) {
171  Messages.confirmMove().show(() -> {
172  try {
173  fillFolder();
174  FileRow row = (FileRow) dp.getDragged();
175  FileUtils.moveFileToDirectory(row.getFile(), getRealFolder(true), false);
176  row.detach();
177  } catch (IOException ex) {
178  Logger.getLogger(FileFolder.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
179  }
180  });
181  }
182  }
183  });
184  appendChild(row);
185  Treecell cell = new Treecell(label);
186  cell.setImage("/_zul/images/folder.png");
187  row.appendChild(cell);
188  }
189 
190  private void addChildrenSpace() {
191  if(!isLeaf()) {
192  children = new Treechildren();
193  appendChild(children);
194  if(!loadOnDemand) {
195  fillFolder();
196  setOpen(true);
197  }
198  }
199  }
200 
201  public boolean isLoadOnDemand() {
202  return loadOnDemand;
203  }
204 
205  public void setLoadOnDemand(boolean loadOnDemand) {
206  this.loadOnDemand = loadOnDemand;
207  }
208 
209  public String getPath() {
210  return path;
211  }
212 
213  public void setPath(String path) {
214  this.path = path;
215  }
216 
217  private void initLoadOnDemand() {
218  if(!loadOnDemand) return;
219 
220  setOpen(false);
221 
222  addEventListener(Events.ON_OPEN, new EventListener() {
223  @Override
224  public void onEvent(Event event) throws Exception {
225  // load files and add folders
226  if(isOpen()) {
227  fillFolder();
228  }
229  }
230  });
231  }
232 
233  private void fillFolder() {
234  if(children != null && children.getChildren().isEmpty()) {
235  for(String s : getFolders()) {
236  addFolder(s, path + "/" + s);
237  }
238  }
239  }
240 
241  @Override
243  return (IAttachFolder) getParentItem();
244  }
245 
246  @Override
247  public String getFolderPath() {
248  return path;
249  }
250 
251  @Override
252  public String getFolderLabel() {
253  return realLabel;
254  }
255 
256  @Override
257  public void setFolderLabel(String label) {
258  setLabel(label);
259  }
260 
261  public void doProcessors() {
262  String shortPath = getPath();
263  if(shortPath.startsWith("/_internal/files")) {
264  shortPath = shortPath.substring(16);
265  } else if(shortPath.startsWith("/WEB-INF/files")) {
266  shortPath = shortPath.substring(14);
267  }
268  String str = Entities.getController(shortPath).getTreeLabel();
269  if(str != null) {
270  setFolderLabel(StringParser.cutString(str, 50));
271  setTooltiptext(str);
272  }
273  }
274 
275  public boolean isLeaf() {
276  return getFolders().isEmpty();
277  }
278 
279  public Collection<String> getFolders() {
280  File folder = getRealFolder(true);
281  FileResults fr = getTree().getResults();
282  return fr.getFolders(folder);
283  }
284 
285  public Collection<FileFolder> getFileFolders() {
286  showContents();
287  return children != null ? CollectionUtil.from(children.getChildren()).<Collection<FileFolder>>cast() : new ArrayList<>();
288  }
289 
290  public Collection<File> getFiles() {
291  File folder = getRealFolder(true);
292  FileResults fr = getTree().getResults();
293  return fr.getFiles(folder);
294  }
295 
296  public Collection<File> getFilesFrom(File folder) {
297  FileResults fr = getTree().getResults();
298  return fr.getFileList(folder);
299  }
300 
301  @Override
302  public void afterCompose() {
303  initLoadOnDemand();
304  addCells();
305  addChildrenSpace();
306  }
307 
308  public File getRealFolder() {
309  return getRealFolder(false);
310  }
311 
312  public File getRealFolder(boolean create) {
313  File folder = new File(ElephantContext.getRealPath(path));
314  if(!folder.exists()) {
315  folder.mkdirs();
316  }
317  return folder;
318  }
319 
320 }
static String cutString(String value, int maxChars)
static Messages confirmMove()
Definition: Messages.java:99
static IElephantEntity getController(String path)
Definition: Entities.java:78
Collection< String > getFolders(File folder)
Collection< File > getFiles(File folder)
Collection< File > getFileList(File folder)
FileFolder(String label, Object value)
Definition: FileFolder.java:78
FileFolder(String label, String path, boolean loadOnDemand)
Definition: FileFolder.java:69
Collection< FileFolder > getFileFolders()
FileFolder addFolder(String label, String path)
void setLoadOnDemand(boolean loadOnDemand)
Collection< File > getFilesFrom(File folder)
static String get(String msg)
Definition: I_.java:41
static void toFolder(Media media, Folder folder)
Definition: Medias.java:50
static void getInput(Page page, String title, String label, Object value, String format, int scale, final Command onOk)