BrightSide Workbench Full Report + Source Code
FileItem.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.file.zul.tree;
19 
20 import java.io.File;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.util.Arrays;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26 import org.amic.util.file.FileUtil;
27 import org.turro.command.Command;
28 import org.turro.command.Context;
29 import org.turro.elephant.context.Application;
30 import org.turro.elephant.context.ElephantContext;
31 import org.turro.elephant.impl.util.StringParser;
32 import org.turro.elephant.util.Messages;
33 import org.turro.entities.Entities;
34 import org.turro.file.FileComparator;
35 import org.turro.file.FileWrapper;
36 import org.turro.i18n.I_;
37 import org.turro.zkoss.dialog.InputDialog;
38 import org.turro.zkoss.dialog.InputField;
39 import org.zkoss.zk.ui.event.DropEvent;
40 import org.zkoss.zk.ui.event.Event;
41 import org.zkoss.zk.ui.event.EventListener;
42 import org.zkoss.zk.ui.event.Events;
43 import org.zkoss.zk.ui.ext.AfterCompose;
44 import org.zkoss.zul.Treechildren;
45 import org.zkoss.zul.Treeitem;
46 import org.zkoss.zul.Treerow;
47 
52 public class FileItem extends Treeitem implements AfterCompose {
53 
54  private Application app = Application.getApplication();
55 
56  private Treerow row;
57  private Treechildren children;
58  private String fileLabel;
59 
60  public FileItem(File file) {
61  this(null, file);
62  }
63 
64  public FileItem(String label, File file) {
65  super();
66  this.fileLabel = label;
67  setValue(file);
68  setOpen(false);
69  addEventListener(Events.ON_OPEN, new EventListener<Event>() {
70  @Override
71  public void onEvent(Event event) throws Exception {
72  processSelection(false);
73  }
74  });
75  //initLoadOnDemand();
76  }
77 
78  public FileItem(String label) {
79  throw new UnsupportedOperationException("Do not use");
80  }
81 
82  public FileItem() {
83  throw new UnsupportedOperationException("Do not use");
84  }
85 
86  @Override
87  public FileTree getTree() {
88  return (FileTree) super.getTree();
89  }
90 
92  return (FileItem) getParentItem();
93  }
94 
95  public String getFileLabel() {
96  return fileLabel;
97  }
98 
99  public void doAddFolder() throws InterruptedException {
101  getPage(),
102  I_.get("Folder"),
103  new InputField[] {
104  new InputField("Name", "", null, 0)
105  }, new Command() {
106  @Override
107  public Object execute(Context context) {
108  InputField[] fields = (InputField[]) context.get("fields");
109  if(fields.length > 0) {
110  for(InputField f : fields) {
111  if("Name".equals(f.getLabel())) {
112  File newFolder = new File(getFile().getAbsolutePath() + "/" + f.getValue());
113  if(newFolder.mkdirs()) {
114  reloadContents();
115  }
116  }
117  }
118  }
119  return null;
120  }
121  });
122  }
123 
124  public void doRename() throws InterruptedException {
125  if(getParentItem() == null) return;
127  getPage(),
128  I_.get("Rename"),
129  new InputField[] {
130  new InputField("Name", getFile().getName(), null, 0)
131  }, new Command() {
132  @Override
133  public Object execute(Context context) {
134  InputField[] fields = (InputField[]) context.get("fields");
135  if(fields.length > 0) {
136  for(InputField f : fields) {
137  if("Name".equals(f.getLabel())) {
138  String path = FileUtil.getParentPath(getFile().getAbsolutePath());
139  if(path != null) {
140  if(getFile().renameTo(new File(path + "/" + f.getValue()))) {
141  FileItem.this.setValue(new File(path + "/" + f.getValue()));
142  FileItem.this.setLabel(getFile().getName());
143  }
144  }
145  }
146  }
147  }
148  return null;
149  }
150  });
151  }
152 
153  public void showContents() {
154  fillFolder();
155  setOpen(true);
156  }
157 
158  public void reloadContents() {
159  if(children != null) {
160  children.getChildren().clear();
161  showContents();
162  }
163  }
164 
165  public File getFile() {
166  return (File) getValue();
167  }
168 
169  public String getPath() {
170  String path = "";
171  FileItem fi = this;
172  while(fi != null) {
173  if(fi.getParentFile() == null) {
174  break;
175  }
176  path = "/" + fi.getFile().getName() + path;
177  fi = fi.getParentFile();
178  }
179  return path;
180  }
181 
182  public void processSelection(boolean openItem) {
183  if(getFile().isDirectory()) {
184  if(openItem) {
185  if(!isOpen()) {
186  showContents();
187  } else {
188  setOpen(false);
189  }
190  } else {
191  if(isOpen()) {
192  showContents();
193  } else {
194  setOpen(false);
195  }
196  }
197  } else {
198  getTree().getActionMenu().open(this);
199  }
200  }
201 
202  public void initPreview() {
203  File file = getValue();
204  if(!file.isDirectory()) {
205  FilePreview fp = new FilePreview(file);
206  getTree().getParent().appendChild(fp);
207  setTooltip(fp);
208  }
209  }
210 
211  private String getMimeImage() {
212  if(!new File(ElephantContext.getRealPath("/_internal/system/mime/" + FileUtil.getExtension((File) getValue()) + ".png")).exists()) {
213  return "/_internal/system/mime/empty.png";
214  } else {
215  return "/_internal/system/mime/" + FileUtil.getExtension((File) getValue()) + ".png";
216  }
217  }
218 
219  private void addCells() {
220  if(row == null) {
221  row = new Treerow();
222  row.setDraggable("true");
223  row.setDroppable(getFile().isDirectory() ? "true" : "false");
224  row.addEventListener(Events.ON_DROP, new EventListener() {
225  @Override
226  public void onEvent(Event event) throws Exception {
227  DropEvent dp = (DropEvent) event;
228  if(getFile().isDirectory() && dp.getDragged().getParent() instanceof FileItem) {
229  final FileItem dragged = (FileItem) dp.getDragged().getParent();
230  Messages.confirmMove().show(() -> {
231  try {
232  FileWrapper fw = new FileWrapper(dragged.getFile());
233  fw.copyTo(getFile());
234  fw.delete();
235  dragged.detach();
236  reloadContents();
237  } catch (IOException ex) {
238  Logger.getLogger(FileItem.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
239  }
240  });
241  }
242  }
243  });
244  appendChild(row);
245  } else {
246  row.getChildren().clear();
247  }
248  for(FileColumn fc : getTree().getColumns()) {
249  row.appendChild(fc.getCell(this));
250  }
251  }
252 
253  private void addChildrenSpace() {
254  children = new Treechildren();
255  appendChild(children);
256  }
257 
258  private void initLoadOnDemand() {
259  if(((File) getValue()).isDirectory()) {
260  setOpen(false);
261  addEventListener(Events.ON_OPEN, new EventListener() {
262  @Override
263  public void onEvent(Event event) throws Exception {
264  // load files and add folders
265  if(isOpen()) {
266  fillFolder();
267  }
268  }
269  });
270  }
271  addEventListener(Events.ON_CLICK, new EventListener() {
272  @Override
273  public void onEvent(Event event) throws Exception {
274  if(((File) getValue()).isDirectory()) {
275  setOpen(!isOpen());
276  } else {
277  getTree().getActionMenu().open(FileItem.this);
278  }
279  }
280  });
281  }
282 
283  private void fillFolder() {
284  if(children.getChildren().isEmpty()) {
285  File file = (File) getValue();
286  if(!file.exists()) {
287  return;
288  }
289  if(file.isDirectory()) {
290  File[] sortedFiles = file.listFiles(getTree().getFileFilter());
291  try {
292  Arrays.sort(sortedFiles, new FileComparator(new FileWrapper(file).getProperties()));
293  } catch (FileNotFoundException ex) {
294  Logger.getLogger(FileItem.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
295  } catch (IOException ex) {
296  Logger.getLogger(FileItem.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
297  }
298  for(File f : sortedFiles) {
299  FileItem fi = new FileItem(f);
300  children.appendChild(fi);
301  fi.initPreview();
302  fi.doProcessors(getPath());
303  fi.setContext(getTree().getActionMenu());
304  if(fi instanceof AfterCompose) {
305  ((AfterCompose) fi).afterCompose();
306  }
307  }
308  }
309  }
310  }
311 
312  @Override
313  public void afterCompose() {
314  addCells();
315  File file = (File) getValue();
316  if(file.isFile()) {
317  setImage(getMimeImage());
318  } else if(!file.exists() || file.isDirectory()) {
319  setImage("/_zul/images/folder.png");
320  addChildrenSpace();
321  }
322  }
323 
324  private void doProcessors(String rootPath) {
325  String str = Entities.getController(rootPath + "/" + getFile().getName()).getName();
326  if(str != null) {
327  fileLabel = StringParser.cutString(str, 50);
328  }
329  }
330 
331 }
static String cutString(String value, int maxChars)
static IElephantEntity getController(String path)
Definition: Entities.java:78
void processSelection(boolean openItem)
Definition: FileItem.java:182
FileItem(String label, File file)
Definition: FileItem.java:64
static String get(String msg)
Definition: I_.java:41
static void getInput(Page page, String title, String label, Object value, String format, int scale, final Command onOk)