📄 filemanager.java
字号:
import java.awt.*;import java.io.*;import java.applet.*;import java.net.*;import java.util.*;import netscape.javascript.JSObject;// A java filemanager that allows the user to manipulate files on the// Webmin server. Layout is similar to the windows explorer - directory// tree on the left, files on the right, action buttons on the top.public class FileManager extends Applet implements CbButtonCallback, HierarchyCallback, MultiColumnCallback{ // top buttons CbButton open_b, view_b, edit_b, refresh_b, props_b, copy_b, cut_b, paste_b, delete_b, new_b, upload_b, mkdir_b, makelink_b, rename_b; // Directory tree Hierarchy dirs; FileNode root; Hashtable nodemap = new Hashtable(); // File list MultiColumn files; TextField pathname; RemoteFile showing_files; // Copying and pasting String cut_buffer; boolean cut_mode; static final String monmap[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; String accroot[]; Hashtable lang = new Hashtable(); public void init() { setLayout(new BorderLayout()); StringTokenizer tok = new StringTokenizer(getParameter("root"), " "); accroot = new String[tok.countTokens()]; for(int i=0; tok.hasMoreTokens(); i++) accroot[i] = tok.nextToken(); // download language strings String l[] = get_text("lang.cgi"); for(int i=0; i<l.length; i++) { int eq = l[i].indexOf('='); lang.put(l[i].substring(0, eq), l[i].substring(eq+1)); } // create button panel BorderPanel top = new BorderPanel(2); top.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2)); Panel top1 = new Panel(); top1.setLayout(new GridLayout(1, 0)); top1.add(open_b = make_button("open.gif", text("top_open"))); top1.add(view_b = make_button("view.gif", text("top_view"))); top1.add(edit_b = make_button("edit.gif", text("top_edit"))); top1.add(refresh_b = make_button("refresh.gif", text("top_refresh"))); top1.add(props_b = make_button("props.gif", text("top_info"))); top.add(top1); top.add(new Label("")); Panel top2 = new Panel(); top2.setLayout(new GridLayout(1, 0)); top2.add(delete_b = make_button("cancel.gif", text("top_delete"))); top2.add(new_b = make_button("new.gif", text("top_new"))); top2.add(upload_b = make_button("upload.gif", text("top_upload"))); top2.add(mkdir_b = make_button("mkdir.gif", text("top_new"))); if (!getParameter("follow").equals("1")) top2.add(makelink_b = make_button("makelink.gif", text("top_new"))); top2.add(rename_b = make_button("rename.gif", text("top_rename"))); top.add(top2); top.add(new Label("")); Panel top3 = new Panel(); top3.setLayout(new GridLayout(1, 0)); top3.add(copy_b = make_button("copy.gif", text("top_copy"))); top3.add(cut_b = make_button("cut.gif", text("top_cut"))); top3.add(paste_b = make_button("paste.gif", text("top_paste"))); top.add(top3); add("North", top); Panel mid = new Panel(); add("Center", mid); mid.setLayout(new GridLayout(1, 2)); // create directory tree BorderPanel left = new BorderPanel(2); left.setLayout(new BorderLayout()); root = new FileNode(new RemoteFile(this, get_text("root.cgi")[0],null)); left.add("Center", dirs = new Hierarchy(root, this)); root.open = true; root.fill(); mid.add(left); // create file window BorderPanel right = new BorderPanel(2); right.setLayout(new BorderLayout()); right.add("North", pathname = new TextField()); //pathname.setFont(new Font("courier", Font.PLAIN, 8)); String cols[] = { "", text("right_name"), text("right_size"), text("right_user"), text("right_group"), text("right_date") }; float widths[] = { .07f, .33f, .15f, .15f, .15f, .15f }; right.add("Center", files = new MultiColumn(cols, this)); files.setWidths(widths); files.setDrawLines(false); show_files(root.file); mid.add(right); // Go to the restricted directory if (!accroot[0].equals("/")) find_directory(accroot[0], true); } CbButton make_button(String f, String t) { return new CbButton(get_image(f), t, CbButton.ABOVE, this); } // Gets an image from the images directory Image get_image(String img) { return getImage(getDocumentBase(), "images/"+img); } String[] get_text(String url) { try { long now = System.currentTimeMillis(); if (url.indexOf('?') > 0) url += "&rand="+now; else url += "?rand="+now; URL u = new URL(getDocumentBase(), url); Vector lv = new Vector(); LineInputStream is = new LineInputStream(u.openStream()); while(true) try { lv.addElement(is.gets()); } catch(EOFException eof) { break; } is.close(); String rv[] = new String[lv.size()]; lv.copyInto(rv); return rv; } catch(Exception e) { e.printStackTrace(); return null; } } // Fill the multicolumn list with files from some directory void show_files(RemoteFile f) { RemoteFile fl[] = f.list(); files.clear(); Object rows[][] = new Object[fl.length+1][]; long now = System.currentTimeMillis(); // Create parent directory rows rows[0] = new Object[6]; rows[0][0] = get_image("dir.gif"); rows[0][1] = ".."; rows[0][2] = rows[0][3] = rows[0][4] = rows[0][5] = ""; // Create file rows for(int i=0; i<fl.length; i++) { Object row[] = rows[i+1] = new Object[6]; row[0] = get_image(RemoteFile.tmap[fl[i].type]); row[1] = fl[i].name; if (fl[i].size < 1000) row[2] = spad(fl[i].size, 5)+" b"; else if (fl[i].size < 1000000) row[2] = spad(fl[i].size/1000, 5)+" Kb"; else row[2] = spad(fl[i].size/1000000, 5)+" Mb"; row[3] = fl[i].user; row[4] = fl[i].group; Date d = new Date(fl[i].modified); if (now - fl[i].modified < 24*60*60*1000) { // show as hour:min row[5] = pad(d.getHours(),2)+":"+ pad(d.getMinutes(),2); } else if (now - fl[i].modified < 24*60*60*365*1000) { // show as day/mon row[5] = pad(d.getDate(),2)+"/"+ monmap[d.getMonth()]; } else { // show as mon/year row[5] = monmap[d.getMonth()]+"/"+ pad(d.getYear()%100, 2); } } files.addItems(rows); showing_files = f; pathname.setText(f.path); } String pad(int n, int s) { String rv = String.valueOf(n); while(rv.length() < s) rv = "0"+rv; return rv; } String spad(int n, int s) { String rv = String.valueOf(n); while(rv.length() < s) rv = " "+rv; return rv; } String trim_path(String p) { while(p.endsWith("/")) p = p.substring(0, p.length()-1); return p; } // openNode // Called when a node with children is opened public void openNode(Hierarchy h, HierarchyNode n) { FileNode fn = (FileNode)n; fn.fill(); } // closeNode // Called when a node is closed public void closeNode(Hierarchy h, HierarchyNode n) { } // clickNode // Called when the user clicks on a node public void clickNode(Hierarchy h, HierarchyNode n) { FileNode fn = (FileNode)n; if (showing_files != fn.file) show_files(fn.file); } // doubleNode // Called when a user double-clicks on a node public void doubleNode(Hierarchy h, HierarchyNode n) { } // Called when a button is clicked public void click(CbButton b) { int s = files.selected(); RemoteFile f = s < 1 ? null : (showing_files.list())[s-1]; FileNode d = (FileNode)dirs.selected(); if (b == edit_b) { // Open a window for editing the selected file if (f == null) return; if (f.type == 0 || f.type > 4) new ErrorWindow(text("edit_enormal")); else new EditorWindow(f, this); } else if (b == view_b) { // View the selected file in the browser if (f == null) return; if (f.type == 0 || f.type > 4) new ErrorWindow(text("view_enormal")); else show_file(f); } else if (b == open_b) { // Open the selected directory d.open = !d.open; d.fill(); dirs.redraw(); } else if (b == refresh_b) { // Refesh the selected directory (and thus any subdirs) d.known = false; d.file.list = null; d.fill(); show_files(d.file); } else if (b == props_b) { // Display the properties window if (f == null) return; new PropertiesWindow(f, this); } else if (b == copy_b) { // Copy the selected file if (f == null) return; cut_buffer = f.path; cut_mode = false; } else if (b == cut_b) { // Cut the selected file if (f == null) return; cut_buffer = f.path; cut_mode = true; } else if (b == paste_b) { // Paste the copied file if (cut_buffer == null) { new ErrorWindow(text("paste_ecopy")); return; } int sl = cut_buffer.lastIndexOf('/'); String cut_name = cut_buffer.substring(sl+1), cut_dir = cut_buffer.substring(0, sl); RemoteFile cut_par = find_directory(cut_dir, false), cut_file; if (cut_par == null || (cut_file = cut_par.find(cut_name)) == null) { new ErrorWindow(text("paste_egone", cut_name)); return; } // Check for an existing file RemoteFile already = showing_files.find(cut_name); String sp = showing_files.path; String dest_path = sp.equals("/") ? sp+cut_name : sp+"/"+cut_name; if (already != null && (already.type == 0 || already.type == 5)) { new ErrorWindow(text("paste_eover", dest_path)); return; } if (already == cut_file) { new ErrorWindow(text("paste_eself")); return; } // Move or copy the actual file String[] rv = get_text((cut_mode ? "move.cgi" : "copy.cgi")+ "?from="+urlize(cut_buffer)+ "&to="+urlize(dest_path)); if (rv[0].length() > 0) { new ErrorWindow(text( cut_mode ? "paste_emfailed" : "paste_ecfailed", rv[0])); return; } RemoteFile file = new RemoteFile(this, rv[1], showing_files); if (already == null) { // Add to the parent directory showing_files.add(file); } else { // Update the existing file already.type = file.type; already.user = file.user; already.group = file.group; already.size = file.size; already.perms = file.perms; already.modified = file.modified; file = already; } if (cut_mode) { // Delete the old file cut_par.delete(cut_file); } if (cut_file.type == 0) { // Moving or copying a directory.. update the tree FileNode dest_par_node = (FileNode)nodemap.get(showing_files); dest_par_node.add(new FileNode(file)); if (cut_mode) { FileNode cut_par_node = (FileNode)nodemap.get(cut_par); FileNode cut_file_node = (FileNode)nodemap.get(cut_file); if (cut_par_node != null && cut_file_node != null) cut_par_node.ch.removeElement( cut_file_node); } dirs.redraw(); } show_files(showing_files); if (cut_mode) { // Paste from the destination path from now on cut_mode = false; cut_buffer = dest_path; } } else if (b == delete_b) { // Delete the selected file if (f == null) return; new DeleteWindow(this, f); } else if (b == new_b) { // Open a window for creating a file new EditorWindow(showing_files.path, this); } else if (b == upload_b) { // Call javascript to open an upload window try { JSObject win = JSObject.getWindow(this); String params[] = { showing_files.path }; win.call("upload", params); } catch(Exception e) { new ErrorWindow(text("upload_efailed", e.getMessage())); } } else if (b == mkdir_b) { // Prompt for new directory new MkdirWindow(showing_files.path, this); } else if (b == makelink_b) { // Prompt for a new symlink new LinkWindow(showing_files.path, this); } else if (b == rename_b) { // Prompt for new filename if (f == null) return; new RenameWindow(this, f); } } // Returns the object for some directory, or null if not found. RemoteFile find_directory(String p, boolean fill) { int l = p.length(); boolean can = false; for(int r=0; r<accroot.length; r++) { int rl = accroot[r].length(); if (accroot[r].equals("/")) can = true; else if (l >= rl && p.substring(0, rl).equals(accroot[r])) can = true; else if (l < rl && accroot[r].substring(0, l).equals(p)) can = true; } if (!can) { new ErrorWindow(text("find_eaccess", p)); return null; } FileNode posnode = root; RemoteFile pos = posnode.file; StringTokenizer tok = new StringTokenizer(p, "/"); while(tok.hasMoreTokens()) { String fn = tok.nextToken(); if (fn.equals("")) continue; RemoteFile fl[] = pos.list(); if (fill) { posnode.open = true; posnode.fill(); } boolean found = false; for(int i=0; i<fl.length; i++) if (fl[i].name.equals(fn)) { pos = fl[i]; found = true; } if (!found) { new ErrorWindow(text("find_eexist", fn, p)); return null; } if (pos.type != 0) { new ErrorWindow(text("find_edir", fn, p)); return null; } if (fill) posnode = (FileNode)nodemap.get(pos); } if (fill) { show_files(pos); posnode.fill(); posnode.open = true; dirs.select(posnode); dirs.redraw();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -