Java tutorial
/* * $Header$ * $Revision: 208205 $ * $Date: 2004-11-27 07:38:49 +0800 (Sat, 27 Nov 2004) $ * * ==================================================================== * * Copyright 1999-2002 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.webdav.cmd; import antlr.RecognitionException; import antlr.TokenStreamException; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.StringTokenizer; import java.util.Vector; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.HttpURL; import org.apache.commons.httpclient.HttpsURL; import org.apache.commons.httpclient.URIException; import org.apache.commons.httpclient.util.URIUtil; import org.apache.webdav.lib.Ace; import org.apache.webdav.lib.Lock; import org.apache.webdav.lib.Privilege; import org.apache.webdav.lib.Property; import org.apache.webdav.lib.PropertyName; import org.apache.webdav.lib.ResponseEntity; import org.apache.webdav.lib.WebdavResource; import org.apache.webdav.lib.methods.DepthSupport; import org.apache.webdav.lib.methods.LockMethod; import org.apache.webdav.lib.properties.AclProperty; import org.apache.webdav.lib.properties.LockDiscoveryProperty; import org.apache.webdav.lib.properties.PrincipalCollectionSetProperty; import org.apache.webdav.lib.properties.ResourceTypeProperty; import org.apache.webdav.lib.util.QName; /** * The Slide client, the command line version for WebDAV client. * */ final class Client { private Spool spool; private InputStream in; private PrintStream out; private boolean displayPrompt = true; /** The path for the display information. */ private String path = ""; /** The command prompt for the display information. */ private String commandPrompt = null; /** The http URL on the client connection. */ private HttpURL httpURL; /** The debug level. */ private int debugLevel = DEBUG_OFF; /** The WebDAV resource. */ private WebdavResource webdavResource = null; /** The current path on the local system. */ private File dir = new File("."); ///////////////////////////////////////////////////////////////// Client(InputStream in, PrintStream out) { this.spool = new Spool(in, out); this.in = in; this.out = new PrintStream(spool.getOutputStream()); updatePrompt(getPath()); } void run() { while (true) { try { InputStream in = spool.getInputStream(); ClientLexer lexer = new ClientLexer(new DataInputStream(in)); ClientParser parser = new ClientParser(lexer); parser.setClient(this); parser.commands(); } catch (TokenStreamException ex) { handleException(ex); } catch (RecognitionException ex) { handleException(ex); } } // TODO test EOF ??? } /////////////////////////////////////////////////////////////////// // Helper funtions for the parser and error handlers /////////////////////////////////////////////////////////////////// void printInvalidCommand(String command) { out.println("Error: invalid command: " + command); } void printUsage(String command) { out.println("Syntax error. \"help\" for more info"); // out.println("Usage: " + command + " ..."); // out.println // ("[Help] open " + // "http://hostname[:port][/path]"); // out.println("Syntax: grant <namespace> <permission> on <path> to <principal>"); // out.println("Syntax: revoke <namespace> <permission> on <path> from <principal>"); // out.println("Syntax: deny <namespace> <permission> on <path> to <principal>"); // out.println("Syntax: lock <path>"); // out.println("Syntax: unlock <path>"); // out.println("Syntax: vc/VersionControl <path>"); // else out.println("Syntax: eReport path"); // else out.println("Syntax: lReport <property> \n History URLs are needed"); } void prompt() { if (displayPrompt) out.print(getPrompt()); } void print(String line) { out.println(line); } private void handleException(Exception ex) { if (ex instanceof HttpException) { if (((HttpException) ex).getReasonCode() == HttpStatus.SC_METHOD_NOT_ALLOWED) { out.println("Warning: Not WebDAV-enabled?"); } else if (((HttpException) ex).getReasonCode() == HttpStatus.SC_UNAUTHORIZED) { out.println("Warning: Unauthorized"); } else { out.println("Warning: " + ex.getMessage()); } } else if (ex instanceof IOException) { out.println("Error: " + ex.getMessage()); } else { out.println("Fatal Error: " + ex.getMessage()); ex.printStackTrace(out); out.println("Please, email to slide-user@jakarta.apache.org"); System.exit(-1); } } ///////////////////////////////////////////////////////////////// // Commands available on the command line ///////////////////////////////////////////////////////////////// void setEchoEnabled(boolean isEnabled) { spool.setEcho(isEnabled); setDisplayPrompt(isEnabled); // if this is an interactive client keep the prompt if (this.in == System.in) setDisplayPrompt(true); } void executeScript(String scriptname) { try { FileInputStream script = new FileInputStream(scriptname); Client scriptClient = new Client(script, out); scriptClient.setDisplayPrompt(false); out.println("Executing script: " + scriptname); scriptClient.run(); out.println("Script " + scriptname + " complete."); script.close(); } catch (FileNotFoundException ex) { out.println("Error: Script " + scriptname + " not found."); } catch (IOException ex) { out.println("Error: " + ex.toString() + " during execution of " + scriptname); } } void enableSpoolToFile(String filename) { out.println("Spool to file: " + filename); try { spool.enable(filename); } catch (FileNotFoundException ex) { out.println("Error: Could not spool to file: " + filename); disableSpoolToFile(); } } void disableSpoolToFile() { spool.disable(); out.println("Spooling disabled"); } /** Debug level for all debug messages */ final static int DEBUG_ON = Integer.MAX_VALUE; /** Debug level for no debug messages */ final static int DEBUG_OFF = 0; /** * Set the debug level */ void setDebug(int level) { this.debugLevel = level; if (webdavResource != null) webdavResource.setDebug(debugLevel); switch (level) { case DEBUG_ON: out.println("The debug flag is on."); break; case DEBUG_OFF: out.println("The debug flag is off."); break; default: out.println("The debug level is " + level); break; } } void connect(String uri) { if (!uri.endsWith("/") && !uri.endsWith("\\")) { // append / to the path uri += "/"; } out.println("connect " + uri); try { // Set up for processing WebDAV resources httpURL = uriToHttpURL(uri); if (webdavResource == null) { webdavResource = new WebdavResource(httpURL); webdavResource.setDebug(debugLevel); // is not a collection? if (!((ResourceTypeProperty) webdavResource.getResourceType()).isCollection()) { webdavResource = null; httpURL = null; out.println("Error: " + uri + " is not a collection! Use open/connect only for collections!"); } } else { webdavResource.close(); webdavResource.setHttpURL(httpURL); } setPath(webdavResource.getPath()); } catch (HttpException we) { out.print("HttpException.getReasonCode(): " + we.getReasonCode()); if (we.getReasonCode() == HttpStatus.SC_UNAUTHORIZED) { try { out.print("UserName: "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String userName = in.readLine(); if ((userName == null) || (userName.length() == 0)) { disconnect(); return; } userName = userName.trim(); System.out.print("Password: "); String password = in.readLine(); if (password != null) password = password.trim(); try { if (webdavResource != null) webdavResource.close(); } catch (IOException e) { } finally { httpURL = null; webdavResource = null; } httpURL = uriToHttpURL(uri); // It should be used like this way. httpURL.setUserinfo(userName, password); webdavResource = new WebdavResource(httpURL); webdavResource.setDebug(debugLevel); setPath(webdavResource.getPath()); if (!((ResourceTypeProperty) webdavResource.getResourceType()).isCollection()) { webdavResource = null; httpURL = null; out.println( "Error: " + uri + " is not a collection! Use open/connect only for collections!"); } } catch (Exception ex) { handleException(ex); httpURL = null; webdavResource = null; } } else { handleException(we); httpURL = null; webdavResource = null; } } catch (Exception ex) { handleException(ex); webdavResource = null; httpURL = null; } updatePrompt(getPath()); } void disconnect() { out.println("disconnect"); try { webdavResource.close(); } catch (IOException e) { } finally { // Make sure the connection closed. httpURL = null; webdavResource = null; } updatePrompt(getPath()); } void options(String path) { out.println("options " + path); String param = path; try { boolean succeeded = false; if (param != null) { if (!param.startsWith("/")) { httpURL = uriToHttpURL(param); Enumeration opts = null; try { // OPTIONS business logic opts = webdavResource.optionsMethod(httpURL); while (opts.hasMoreElements()) { out.print(opts.nextElement()); if (opts.hasMoreElements()) { out.print(", "); } else { out.println(); } } } catch (HttpException we) { if (we.getReasonCode() == HttpStatus.SC_UNAUTHORIZED) { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); out.print("UserName: "); String userName = in.readLine(); if (userName != null && userName.length() > 0) { userName = userName.trim(); out.print("Password: "); String password = in.readLine(); if (password != null) password = password.trim(); try { // OPTIONS business logic httpURL.setUserinfo(userName, password); opts = webdavResource.optionsMethod(httpURL); while (opts.hasMoreElements()) { out.print(opts.nextElement()); if (opts.hasMoreElements()) { out.print(", "); } else { out.println(); } } } catch (Exception e) { out.println("Error: " + e.getMessage()); } } } else { out.println("Error: " + we.getMessage()); } } catch (IOException e) { out.println("Error: Check! " + e.getMessage()); } httpURL = null; return; } else if (webdavResource != null) { succeeded = webdavResource.optionsMethod(param); } else { out.println("Not connected yet."); } } else if (webdavResource != null) { succeeded = webdavResource.optionsMethod("*"); } else { out.println("Not connected yet."); } if (succeeded) { out.print("Allowed methods by http OPTIONS: "); Enumeration allowed = webdavResource.getAllowedMethods(); while (allowed.hasMoreElements()) { out.print(allowed.nextElement()); if (allowed.hasMoreElements()) out.print(", "); } Enumeration davCapabilities = webdavResource.getDavCapabilities(); if (davCapabilities.hasMoreElements()) out.print("\nDAV: "); while (davCapabilities.hasMoreElements()) { out.print(davCapabilities.nextElement()); if (davCapabilities.hasMoreElements()) out.print(", "); } out.println(); } } catch (Exception ex) { handleException(ex); } } void help(String topic) { if (topic == null) { printSlideClientUsage(); } else { out.println("No help available on " + topic); } } void lpwd() { try { out.println(dir.getCanonicalPath()); } catch (IOException ex) { out.println("Warning: Not found the path"); } } private File getFileByPath(String path) { if (path != null) { // set a new file if '\' or '/' at the begin of path // or ':' at the 2nd position of path exists. // if not: take the old parent entry of file and add a '/' to path. return (path.startsWith("/") || path.startsWith("\\") || ((path.length() > 1) && (path.charAt(1) == ':'))) ? new File(path) : new File(dir, "/" + path); } else { return dir; } } void lcd(String path) { File anotherDir = getFileByPath(path); if (anotherDir.isDirectory()) { dir = anotherDir; } else { out.println("Warning: path not found!"); } updatePrompt(getPath()); } void lls(String options, String path) { // set default option. char option = 'F'; if ((options != null) && (options.indexOf('l') > 0)) option = 'l'; File temp = getFileByPath(path); if (!temp.exists() || !temp.isDirectory()) { out.println("Warning: path not found!"); return; } String[] list = temp.list(); // TODO: consider of options like '-a' for all and so on. switch (option) { case 'l': for (int i = 0; i < list.length; i++) { String s = list[i]; File file = new File(temp, s); for (int j = 0; j < 4; j++) { switch (j) { case 0: // Print the filename. out.print(s); for (int k = list[i].length(); k < 35; k++) out.print(" "); break; case 1: s = Long.toString(file.length()); for (int k = 10 - s.length(); k > 0; k--) out.print(" "); // don't cut the size. out.print(s + " "); break; case 2: // cut the description. s = file.isDirectory() ? "DIR" : ""; out.print(" " + ((s.length() > 5) ? s.substring(0, 5) : s)); for (int k = s.length(); k < 5; k++) out.print(" "); break; case 3: s = new SimpleDateFormat().format(new Date(file.lastModified())); out.print(" " + s); default: } } // Start with a new line. out.println(); } break; case 'F': int i = 0; for (; i < list.length; i++) { out.print(list[i] + " "); for (int j = list[i].length(); j < 25; j++) { out.print(" "); } if (i % 3 == 2) out.println(); } if (list.length > 0 && i % 3 != 0) { out.println(); } break; default: } // end of switch } void pwc() { out.println(getPath()); } void cd(String path) { String currentPath = webdavResource.getPath(); try { String cdPath = checkUri(path + "/"); webdavResource.setPath(cdPath); if (webdavResource.exists()) { if (webdavResource.isCollection()) { setPath(webdavResource.getPath()); } else { out.println("Warning: Not a collection"); webdavResource.setPath(currentPath); } } else { out.println("Warning: Not found the path"); webdavResource.setPath(currentPath); } } catch (Exception ex) { handleException(ex); try { webdavResource.setPath(currentPath); } catch (Exception e) { handleException(e); } } updatePrompt(getPath()); } void ls(String options, String path) { // set default option. char option = 'F'; if ((options != null) && (options.indexOf('l') > 0)) option = 'l'; try { // Check that the path is ok. if (path != null) { path = checkUri(path + "/"); webdavResource.setPath(path); } else { path = checkUri("./"); webdavResource.setPath(path); } switch (option) { case 'l': Vector basiclist = webdavResource.listBasic(); for (int i = 0; i < basiclist.size(); i++) { String[] longFormat = (String[]) basiclist.elementAt(i); // name -> position 4 String s = longFormat[4]; int len = s.length(); out.print(s); for (int k = len; k < 20; k++) out.print(" "); // size -> position 1 s = longFormat[1]; len = s.length(); for (int k = 10 - len; k > 0; k--) out.print(" "); // don't cut the size. out.print(s + " "); // description -> position 2 // cut the description. s = longFormat[2]; len = s.length(); out.print(" " + ((len > 20) ? s.substring(0, 20) : s)); for (int k = len; k < 20; k++) out.print(" "); // date -> position 3 s = longFormat[3]; len = s.length(); out.println(" " + s); } break; case 'F': String[] list = webdavResource.list(); if (list != null) { int i = 0; for (; i < list.length; i++) { out.print(list[i] + " "); for (int j = list[i].length(); j < 25; j++) { out.print(" "); } if (i % 3 == 2) out.println(); } if (list.length > 0 && i % 3 != 0) out.println(); } break; default: } // end of switch } catch (Exception ex) { handleException(ex); } } void propfind(String path, Vector properties) { try { path = checkUri(path); out.print("Getting properties '" + path + "': "); Enumeration propertyValues = webdavResource.propfindMethod(path, properties); if (propertyValues.hasMoreElements()) { while (propertyValues.hasMoreElements()) { out.println(propertyValues.nextElement()); } } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void status() { out.println(webdavResource.getStatusMessage()); } void propfindall(String path) { try { path = checkUri(path); out.print("Getting properties '" + path + "': "); Enumeration responses = webdavResource.propfindMethod(path, DepthSupport.DEPTH_0); if (!responses.hasMoreElements()) { out.println("failed (no response received)."); out.println(webdavResource.getStatusMessage()); return; } else { out.println(); } ResponseEntity response = (ResponseEntity) responses.nextElement(); Enumeration properties = response.getProperties(); while (properties.hasMoreElements()) { Property property = (Property) properties.nextElement(); out.println(" " + property.getName() + " : " + property.getPropertyAsString()); } } catch (Exception ex) { handleException(ex); } } void proppatch(String path, String prop, String value) { String name = prop; try { path = checkUri(path); out.print("Putting property(" + name + ", " + value + ") to '" + path + "': "); if (webdavResource.proppatchMethod(path, new PropertyName("DAV:", name), value, true)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } String getLocalTragetFileName(String path, String filename) { String srcFileName = null; String tarFileName = null; // get traget filename from last portion of path StringTokenizer st = new StringTokenizer(path, "/\\"); while (st.hasMoreTokens()) { srcFileName = st.nextToken(); } File targetFile = getFileByPath((filename != null) ? filename : srcFileName); try { if (targetFile.isDirectory()) { tarFileName = targetFile.getCanonicalPath() + "/" + srcFileName; } else { tarFileName = targetFile.getCanonicalPath(); } } catch (IOException e) { System.err.println(e.toString()); return null; } return tarFileName; } void get(String path, String filename) { filename = getLocalTragetFileName(path, filename); try { // The resource on the remote. String src = checkUri(path); // The file on the local. String dest = (filename != null) ? filename : URIUtil.getName(src.endsWith("/") ? src.substring(0, src.length() - 1) : src); out.println("get " + src + " " + dest); // For the overwrite operation; String y = "y"; File file = new File(dest); // Checking the local file. if (file.exists()) { // FIXME: interactive ? out.print("Aleady exists. " + "Do you want to overwrite it(y/n)? "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); y = in.readLine(); } if (y.trim().equalsIgnoreCase("y") || (y != null && y.length() == 0)) { out.print("Downloading '" + src + "' to '" + dest + "': "); if (webdavResource.getMethod(src, file)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } } catch (Exception ex) { handleException(ex); } } String getRemoteTragetFileName(String filename, String path) { String srcPathName = null; String target = null; // get traget filename from last portion of filename StringTokenizer st = new StringTokenizer(filename, "/\\"); while (st.hasMoreTokens()) { srcPathName = st.nextToken(); } try { if (path != null) { target = checkUri(path); // check is path a collection ? String currentPath = webdavResource.getPath(); webdavResource.setPath(target); if (webdavResource.exists()) { if (webdavResource.isCollection()) { target += "/" + srcPathName; } } webdavResource.setPath(currentPath); } else { target = checkUri(getPath() + "/" + srcPathName); } } catch (Exception ex) { } return target; } void put(String filename, String path) { String y = "y"; try { String src = filename; String dest = getRemoteTragetFileName(filename, path); String currentPath = webdavResource.getPath(); try { webdavResource.setPath(dest); if (webdavResource.exists()) { out.print("Aleady exists. " + "Do you want to overwrite it(y/n)? "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); y = in.readLine(); } webdavResource.setPath(currentPath); } catch (Exception ex) { } if (y.trim().equalsIgnoreCase("y") || (y != null && y.length() == 0)) { File file = getFileByPath(src); if (file.exists()) { out.print("Uploading '" + file.getCanonicalPath() + "' to '" + dest + "' "); if (webdavResource.putMethod(dest, file)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } else { out.println("Warning: File not exists"); } } } catch (Exception ex) { handleException(ex); } } // TODO multi void delete(String path) { try { path = checkUri(path); out.print("Deleting '" + path + "': "); if (webdavResource.deleteMethod(path)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } // TODO multi void mkcol(String path) { try { path = checkUri(path); out.print("Making '" + path + "' collection: "); if (webdavResource.mkcolMethod(path)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void copy(String src, String dst) { try { src = checkUri(src); dst = checkUri(dst); out.print("Copying '" + src + "' to '" + dst + "': "); if (webdavResource.copyMethod(src, dst)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void move(String src, String dst) { try { src = checkUri(src); dst = checkUri(dst); out.print("Moving '" + src + "' to '" + dst + "': "); if (webdavResource.moveMethod(src, dst)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void locks(String path) { try { path = checkUri(path); LockDiscoveryProperty lockDiscoveryProperty = webdavResource.lockDiscoveryPropertyFindMethod(path); if (lockDiscoveryProperty == null) { out.println("Server did not return a LockDiscoveryProperty."); out.println(webdavResource.getStatusMessage()); return; } Lock[] locks = lockDiscoveryProperty.getActiveLocks(); showLocks(path, locks); } catch (Exception ex) { handleException(ex); } } void lock(String path, String timeout, String scope, String owner) { try { // Test the parameter // // Timeout int to = 0; if ((timeout != null) && (timeout.toLowerCase().substring(0, 5).equals("-tinf"))) { //infinite to = LockMethod.TIMEOUT_INFINITY; } else { to = (timeout == null) ? 120 : Integer.parseInt(timeout.substring(2)); } // scope short scopeType = ((scope != null) && (scope.substring(2).toLowerCase().equals("shared"))) ? LockMethod.SCOPE_SHARED : LockMethod.SCOPE_EXCLUSIVE; // owner owner = (owner != null) ? (owner.substring(2)) : owner; path = checkUri(path); out.print("Locking '" + path + "' "); out.print((owner != null) ? "owner:'" + owner + "' " : ""); out.print("scope:" + scopeType + " timeout:" + to + " :"); if (webdavResource.lockMethod(path, owner, to, scopeType)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void unlock(String path, String owner) { try { // Test the parameter // // owner owner = (owner != null) ? (owner.substring(2)) : owner; path = checkUri(path); out.print("Unlocking '" + path + "'"); out.print((owner != null) ? (" owner:" + owner + ": ") : (": ")); if (webdavResource.unlockMethod(path, owner)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void grant(String permission, String path, String principal) { grant(new QName("DAV:", permission), path, principal); // FIME lookup permission ? // if (namespace==null) { // namespace=resolveNamespace(permission); // if (namespace==null) { // out.println("Could not resolve namespace for permission " + permission); // continue; // } // } } void grant(QName permission, String path, String principal) { try { principal = checkPrincipal(principal, webdavResource, path); grant(webdavResource, permission, path, principal); } catch (Exception ex) { handleException(ex); } } void deny(String permission, String path, String principal) { deny(new QName("DAV:", permission), path, principal); } void deny(QName permission, String path, String principal) { try { principal = checkPrincipal(principal, webdavResource, path); deny(webdavResource, permission, path, principal); } catch (Exception ex) { handleException(ex); } } void revoke(String permission, String path, String principal) { revoke(new QName("DAV:", permission), path, principal); } void revoke(QName permission, String path, String principal) { try { principal = checkPrincipal(principal, webdavResource, path); revoke(webdavResource, permission, path, principal); } catch (Exception ex) { handleException(ex); } } void acl(String path) { try { AclProperty acl = null; if (path != null) { path = checkUri(path); } else { path = webdavResource.getPath(); } acl = webdavResource.aclfindMethod(path); if (acl == null) { out.println("Error: PropFind didn't return an AclProperty!"); return; } out.println(); showAces(path, acl.getAces()); } catch (Exception ex) { handleException(ex); } } void principalcollectionset(String path) { try { PrincipalCollectionSetProperty set = null; if (path != null) { path = checkUri(path); } else { path = webdavResource.getPath(); } set = webdavResource.principalCollectionSetFindMethod(path); if (set == null) { out.println("Error: PropFind didn't return an PrincipalCollectionSetProperty!"); return; } String[] hrefs = set.getHrefs(); if (hrefs == null) { out.println("No PrincipalCollectionSet for " + path); } out.println(); out.println("PrincipalCollectionSet for " + path + ":"); for (int i = 0; i < hrefs.length; i++) out.println(" " + hrefs[i]); out.println(); } catch (Exception ex) { } } /////////////////////////////////////////////////////////////////// void checkin(String path) { try { path = checkUri(path); out.print("checking in '" + path + "': "); if (webdavResource.checkinMethod(path)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void checkout(String path) { try { path = checkUri(path); out.print("checking out '" + path + "': "); if (webdavResource.checkoutMethod(path)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void uncheckout(String path) { try { path = checkUri(path); out.print("unchecking out '" + path + "': "); if (webdavResource.uncheckoutMethod(path)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void versioncontrol(String path) { try { path = checkUri(path); out.print("setting up VersionControl '" + path + "': "); if (webdavResource.versionControlMethod(path)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void versioncontrol(String target, String path) { try { path = checkUri(path); out.print("creating versioncontroled Resource '" + target + "' based on '" + path + "' : "); if (webdavResource.versionControlMethod(path, target)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void report(String path, Vector properties) { Enumeration propertyValues; try { path = checkUri(path); out.println("Getting version-tree Report of '" + path + "':"); if ((properties != null) && (properties.size() > 0)) { propertyValues = webdavResource.reportMethod(uriToHttpURL(path), properties, 1); } else { propertyValues = webdavResource.reportMethod(uriToHttpURL(path), 1); } if (propertyValues.hasMoreElements()) { while (propertyValues.hasMoreElements()) { out.println(propertyValues.nextElement().toString()); } } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void ereport(String path, String srcFilename) { try { String sQuery = ""; if (srcFilename == null) { sQuery = "<D:expand-property xmlns:D='DAV:'><D:property name='version-history'><D:property name='version-set'><D:property name='successor-set'><D:property name='comment'/></D:property></D:property></D:property></D:expand-property>"; } else { File file = new File(dir.getCanonicalPath(), srcFilename); if (!file.exists()) { out.println("report src file not found"); return; } InputStream isQuery = new FileInputStream(file); BufferedReader reader = new BufferedReader(new InputStreamReader(isQuery)); while (reader.ready()) { sQuery += reader.readLine(); } reader.close(); sQuery.replace('\t', ' '); out.println(sQuery); } path = checkUri(path); out.println("expand-property Report of '" + path + "':"); Enumeration propertyValues = webdavResource.reportMethod(uriToHttpURL(path), sQuery, 1); if (propertyValues.hasMoreElements()) { while (propertyValues.hasMoreElements()) { out.println(displayXML(propertyValues.nextElement().toString(), 0)); } } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } /** * lreport path properties on historyUris */ void lreport(String path, Vector properties, Vector historyUris) { try { path = checkUri(path); out.println("Getting version-tree Report of '" + path + "':"); Enumeration propertyValues = webdavResource.reportMethod(uriToHttpURL(path), properties, historyUris, 1); if (propertyValues.hasMoreElements()) { while (propertyValues.hasMoreElements()) { out.println(propertyValues.nextElement().toString()); } } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void mkws(String path) { try { path = checkUri(path); out.print("Making '" + path + "' workspace: "); if (webdavResource.mkWorkspaceMethod(path)) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } /** * Update * * @param path * @param version */ void update(String path, String version) { try { path = checkUri(path); out.print("Updateing resource " + path + ": "); if (webdavResource.updateMethod(path, version)) { out.println("succeeded."); } else { out.println("failed!"); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void beginTransaction(String timeout, String owner) { try { checkUri(null); // Test the parameter // // Timeout int to = 0; if ((timeout != null) && (timeout.toLowerCase().substring(0, 5).equals("-tinf"))) { //infinite to = LockMethod.TIMEOUT_INFINITY; } else { to = (timeout == null) ? 120 : Integer.parseInt(timeout.substring(2)); } // owner owner = (owner != null) ? (owner.substring(2)) : owner; out.print("Starting transaction "); if (webdavResource.startTransaction(owner, to)) { out.println("succeeded."); out.println("Handle: '" + webdavResource.getTransactionHandle() + "'"); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void commitTransaction() { try { checkUri(null); out.print("Committing transaction: '" + webdavResource.getTransactionHandle() + "' "); if (webdavResource.commitTransaction()) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } void abortTransaction() { try { checkUri(null); out.print("Rolling back transaction: '" + webdavResource.getTransactionHandle() + "' "); if (webdavResource.abortTransaction()) { out.println("succeeded."); } else { out.println("failed."); out.println(webdavResource.getStatusMessage()); } } catch (Exception ex) { handleException(ex); } } /////////////////////////////////////////////////////////////////// // Support methods /////////////////////////////////////////////////////////////////// private void setDisplayPrompt(boolean displayPrompt) { this.displayPrompt = displayPrompt; } /** * Determine which URI to use at the prompt. * * @param uri the path to be set. * @return the absolute path. */ private String checkUri(String uri) throws IOException { if (webdavResource == null) { throw new IOException("Not connected yet."); } if (uri == null) { uri = webdavResource.getPath(); } if (!uri.startsWith("/")) { uri = getPath() + uri; } return normalize(uri); } private String checkPrincipal(String principal, WebdavResource webdavResource, String path) throws HttpException, IOException { // Do not complete reserved words String[] types = { "all", "authenticated", "unauthenticated", "property", "self" }; for (int i = 0; i < types.length; i++) { if (types[i].equals(principal)) return principal; } // FIXME: when search support is complete enhance this // to really search for the principal if (!principal.startsWith("/") && !principal.startsWith("http")) { PrincipalCollectionSetProperty set = webdavResource.principalCollectionSetFindMethod(path); if ((set != null) && (set.getHrefs() != null) && (set.getHrefs().length == 1)) principal = set.getHrefs()[0] + "/" + principal; } return normalize(principal); } /** * Set the path. * * @param path the path string. */ private void setPath(String path) { if (!path.endsWith("/")) { path = path + "/"; } this.path = normalize(path); } /** * Get the path. * * @return the path string. */ private String getPath() { return path; } /** * Update the command prompt for the display. * * @param path the path string */ private void updatePrompt(String path) { StringBuffer buff = new StringBuffer(); try { buff.append("[" + httpURL.getHost().toUpperCase() + ":"); buff.append(path + "] "); buff.append(dir.getCanonicalPath()); } catch (Exception e) { buff.append("[ Slide ]"); } buff.append(" $ "); commandPrompt = buff.toString(); } /** * Get the prompt. * * @return the prompt to be displayed. */ private String getPrompt() { return commandPrompt; } /** * Return a context-relative path, beginning with a "/", that represents * the canonical version of the specified path after ".." and "." elements * are resolved out. If the specified path attempts to go outside the * boundaries of the current context (i.e. too many ".." path elements * are present), return <code>null</code> instead. * * @param path the path to be normalized. * @return the normalized path. */ private String normalize(String path) { if (path == null) return null; String normalized = path; // Normalize the slashes and add leading slash if necessary if (normalized.indexOf('\\') >= 0) normalized = normalized.replace('\\', '/'); if (!normalized.startsWith("/")) normalized = "/" + normalized; // Resolve occurrences of "/./" in the normalized path while (true) { int index = normalized.indexOf("/./"); if (index < 0) break; normalized = normalized.substring(0, index) + normalized.substring(index + 2); } // Resolve occurrences of "/../" in the normalized path while (true) { int index = normalized.indexOf("/../"); if (index < 0) break; if (index == 0) return ("/"); // The only left path is the root. int index2 = normalized.lastIndexOf('/', index - 1); normalized = normalized.substring(0, index2) + normalized.substring(index + 3); } // Resolve occurrences of "//" in the normalized path while (true) { int index = normalized.indexOf("//"); if (index < 0) break; normalized = normalized.substring(0, index) + normalized.substring(index + 1); } // Return the normalized path that we have completed return (normalized); } /** * Print the Slide client commands for use */ private void printSlideClientUsage() { out.println("Commands:"); out.println(" options {http_URL|path} " + "Print available http methods"); out.println(" open [http_URL] " + "Connect to specified URL"); out.println(" close " + "Close current connection"); out.println(" exit " + "Exit Slide"); out.println(" help " + "Print this help message"); out.println(" debug {ON|OFF} " + "set debugmode"); out.println(" lpwd " + "Print local working directory"); out.println(" lcd [path] " + "Change local working directory"); out.println(" lls [-lF] [path] " + "List contents of local directory"); out.println(" pwc " + "Print working collection"); out.println(" cc [path] " + "Change working collection"); out.println(" ls [-lF] [path] " + "List contents of collection"); out.println(" url " + "Print working URL"); out.println(" status " + "Print latest http status message"); out.println(" get path [file] " + "Get a resource to a file"); out.println(" put {URL|file} [path] " + "Put a given file or URL to path"); out.println(" mkcol path ... " + "Make new collections"); out.println(" delete path ... " + "Delete resources"); out.println(" copy source destination " + "Copy resource from source to destination path"); out.println(" move source destination " + "Move resource from source to destination path"); out.println(" lock path [-t(xxx|inf)] " + "[-s(SHARED|EXCLUSIVE)] [-oOWNER]\n" + " " + "Lock specified resource.\n" + " " + "default:\n" + " " + "lock file -t120 -sexclusive with current owner"); out.println(" unlock path [-oOWNER] " + "Unlock specified resource.\n" + " " + "default:\n" + " " + "unlock file with current owner"); out.println(" locks [<path>] " + "Displays locks on specified resource"); out.println(" propget path property ... " + "Print value of specified property"); out.println(" propgetall [<path>] " + "Print value of all properties"); out.println(" propput path property value " + "Set property with given value"); out.println(" set URLencode {on|off} " + "Set URL encoding flag, default: on"); out.println(" set debug {on|off} " + "Set debug level, default: off"); out.println(" acl [<path>] " + "Displays the ACL of path"); out.println(" principalcol [<path>] " + "Displays the principal collection set of path"); out.println(" grant [<namespace>] <permission> [on <path>] to <principal>"); out.println(" deny [<namespace>] <permission> [on <path>] to <principal>"); out.println(" revoke [<namespace>] <permission> [on <path>] from <principal>"); out.println(" versioncontrol path " + "set a versionable resource under versioncontrol"); out.println(" versioncontrol URL path " + "create a new versioncontrolled resource at path based on history URL"); out.println(" checkout path " + "checkout of a checkedin resource"); out.println(" checkin path " + "checkin of a checkedout resource"); out.println(" uncheckout path " + "undoing changes on Resource since checkedout (including checkout)"); out.println(" report path [<property>] " + "getting report (version-tree) for any resource"); out.println(" eReport path " + "getting report (expand-property) for any resource"); out.println(" LReport path [<property>] ON [<historyuri>] " + "getting report (locate-by-history)"); out.println(" mkws path ... " + "Make new workspace"); out.println(" update path target " + "Update a resource identified by path to version identified by target"); out.println(" begin starts a new transaction (only if server supports this)"); out.println( " commit commits the transaction started by begin (only if server supports this)"); out.println( " abort aborts and rolls back the transaction started by begin (only if server supports this)"); out.println("Aliases: help=?, open=connect, ls=dir, pwc=pwd, cc=cd, " + "lls=ldir, copy=cp,\n move=mv, delete=del=rm, mkcol=mkdir, " + "propget=propfind, propput=proppatch,\n exit=quit=bye"); out.println("Comment : Once executed, the debug mode will " + "be active.\n\t\tBecause it's not triggered by " + "methods yet."); } /** * Sleep */ // private static void pause(int secs) // { // // try { // Thread.sleep( secs * 1000 ); // } catch( InterruptedException ex ) { // } // } // private String resolveNamespace(String permission) // { // String DEFAULT_NAMESPACE = "DAV:"; // String SLIDE_NAMESPACE = "http://jakarta.apache.org/slide/"; // String namespace=null; // // if (permission==null) // return null; // // if ((permission.equalsIgnoreCase("all")) || // (permission.equalsIgnoreCase("read")) || // (permission.equalsIgnoreCase("write")) || // (permission.equalsIgnoreCase("read-acl")) || // (permission.equalsIgnoreCase("write-acl"))) // { // namespace=DEFAULT_NAMESPACE; // } // // if ((permission.equalsIgnoreCase("read-object")) || // (permission.equalsIgnoreCase("read-revision-metadata")) || // (permission.equalsIgnoreCase("read-revision-content")) || // (permission.equalsIgnoreCase("create-object")) || // (permission.equalsIgnoreCase("remove-object")) || // (permission.equalsIgnoreCase("lock-object")) || // (permission.equalsIgnoreCase("read-locks")) || // (permission.equalsIgnoreCase("create-revision-metadata")) || // (permission.equalsIgnoreCase("modify-revision-metadata")) || // (permission.equalsIgnoreCase("remove-revision-metadata")) || // (permission.equalsIgnoreCase("create-revision-content")) || // (permission.equalsIgnoreCase("modify-revision-content")) || // (permission.equalsIgnoreCase("remove-revision-content")) || // (permission.equalsIgnoreCase("grant-permission")) || // (permission.equalsIgnoreCase("revoke-permission"))) // { // namespace=SLIDE_NAMESPACE; // } // // return namespace; // } private boolean grant(WebdavResource webdavResource, QName permission, String path, String principal) throws HttpException, IOException { out.println("grant " + permission + " on " + path + " to " + principal); return addPermission(webdavResource, permission, path, principal, false); } private boolean deny(WebdavResource webdavResource, QName permission, String path, String principal) throws HttpException, IOException { out.println("deny " + permission + " on " + path + " to " + principal); return addPermission(webdavResource, permission, path, principal, true); } private boolean revoke(WebdavResource webdavResource, QName permission, String path, String principal) throws HttpException, IOException { out.println("revoke " + permission + " on " + path + " from " + principal); return removePermission(webdavResource, permission, path, principal); } private boolean addPermission(WebdavResource webdavResource, QName permission, String path, String principal, boolean negative) throws HttpException, IOException { AclProperty acl = webdavResource.aclfindMethod(path); if (acl == null) { out.println("Error: PropFind didn't return an AclProperty!"); return false; } Ace[] aces = acl.getAces(); if (aces == null) aces = new Ace[0]; if (debugLevel > 5) { out.println(); out.println("ACL from server"); showAces(path, aces); } Ace ace = null; for (int i = 0; i < aces.length && (ace == null); i++) { if ((aces[i].isNegative() == negative) && !aces[i].isProtected() && !aces[i].isInherited() && aces[i].getPrincipal().equals(principal)) { if (debugLevel > 5) out.println("found ace"); ace = aces[i]; } } if (ace == null) { Ace[] oldAces = aces; aces = new Ace[oldAces.length + 1]; System.arraycopy(oldAces, 0, aces, 0, oldAces.length); ace = new Ace(principal, negative, false, false, null); aces[oldAces.length] = ace; } Privilege privilege = new Privilege(permission.getNamespaceURI(), permission.getLocalName(), null); ace.addPrivilege(privilege); if (debugLevel > 5) { out.println(); out.println("ACL with updated privileges"); showAces(path, aces); } boolean success = webdavResource.aclMethod(path, aces); if (!success) out.println(webdavResource.getStatusMessage()); if (debugLevel > 5) { acl = webdavResource.aclfindMethod(path); if (acl == null) out.println("Error: PropFind didn't return an AclProperty!"); else { aces = acl.getAces(); out.println(); out.println("ACL from server after update"); showAces(path, aces); } } return success; } private boolean removePermission(WebdavResource webdavResource, QName permission, String path, String principal) throws HttpException, IOException { AclProperty acl = webdavResource.aclfindMethod(path); if (acl == null) { out.println("Error: PropFind didn't return an AclProperty!"); return false; } Ace[] aces = acl.getAces(); if (aces == null) { out.println("Privilege not found"); return false; } if (debugLevel > 5) { out.println(); out.println("ACL from server"); showAces(path, aces); } boolean found = false; Privilege privilege = new Privilege(permission.getNamespaceURI(), permission.getLocalName(), null); for (int i = 0; i < aces.length; i++) { if (!aces[i].isProtected() && !aces[i].isInherited() && aces[i].getPrincipal().equals(principal)) { if (debugLevel > 5) out.println("found ace"); boolean removed = aces[i].removePrivilege(privilege); found = found || removed; if (removed) out.println("Privilege removed"); } } if (!found) { out.println("Privilege not found"); return false; } if (debugLevel > 5) { out.println(); out.println("ACL with updated privileges"); showAces(path, aces); } boolean success = webdavResource.aclMethod(path, aces); if (!success) out.println(webdavResource.getStatusMessage()); if (debugLevel > 5) { acl = webdavResource.aclfindMethod(path); if (acl == null) out.println("Error: PropFind didn't return an AclProperty!"); else { aces = acl.getAces(); out.println(); out.println("ACL from server after update"); showAces(path, aces); } } return success; } private void showAces(String path, Ace[] aces) { if ((aces == null) || (aces.length == 0)) { out.println("ACL for " + path + " is empty."); return; } out.println("ACL for " + path + ":"); out.println("------------------------------------------------------------"); for (int i = 0; i < aces.length; i++) { Ace ace = aces[i]; out.println((!ace.isNegative() ? "granted" : "denied") + " to " + ace.getPrincipal() + " " + " (" + (ace.isProtected() ? "protected" : "not protected") + ")" + " (" + (ace.isInherited() ? ("inherited from '" + ace.getInheritedFrom() + "'") : "not inherited") + ")"); Enumeration privileges = ace.enumeratePrivileges(); while (privileges.hasMoreElements()) { Privilege priv = (Privilege) privileges.nextElement(); out.println(" " + priv.getNamespace() + priv.getName() + " " + (priv.getParameter() == null ? "" : ("(" + priv.getParameter() + ")"))); } } out.println("------------------------------------------------------------"); } private void showLocks(String path, Lock[] locks) { if ((locks == null) || (locks.length == 0)) { out.println("No locks on " + path); return; } out.println("Locks for " + path + ":"); out.println("------------------------------------------------------------"); for (int i = 0; i < locks.length; i++) { int lockScope = locks[i].getLockScope(); if (lockScope == Lock.SCOPE_EXCLUSIVE) { out.print("Exclusive "); } else if (lockScope == Lock.SCOPE_SHARED) { out.print("Shared "); } else if (lockScope == -1) { out.print("Unknown scope "); } else { out.println("!!! Internal error !!!"); return; } int lockType = locks[i].getLockType(); if (lockType == Lock.TYPE_WRITE) { out.println("write lock"); } else if (lockType == -1) { out.println("unknown type"); } else { out.println("!!! Internal error !!!"); return; } int depth = locks[i].getDepth(); if (depth == DepthSupport.DEPTH_INFINITY) { out.println(" depth: infinity"); } else if (depth == -1) { // unknown } else { out.println(" depth: " + depth); } String owner = locks[i].getOwner(); if (owner != null) out.println(" owner: " + owner); int timeout = locks[i].getTimeout(); if (timeout != -1) out.println(" timeout: " + timeout); String token = locks[i].getLockToken(); if (token != null) out.println(" token: " + token); } } private String displayXML(String xmlString, int count) { String sResult = ""; if (xmlString.startsWith("</")) { count--; //out.println("cl: " + count); for (int cc = count; cc > 0; cc--) { sResult += "\t"; } try { sResult += xmlString.substring(0, xmlString.indexOf(">") + 1) + "\n"; xmlString = xmlString.substring(xmlString.indexOf(">") + 1); //count --; sResult += displayXML(xmlString, count); } catch (Exception any) { //sResult += "endtag" + any; } } else if (xmlString.startsWith("<")) { //out.println("op: " + count); for (int cc = count; cc > 0; cc--) { sResult += "\t"; } try { sResult += xmlString.substring(0, xmlString.indexOf(">") + 1) + "\n"; xmlString = xmlString.substring(xmlString.indexOf(">") + 1); count++; sResult += displayXML(xmlString, count); } catch (Exception any) { //sResult += "starttag" + any; } } else { //out.println("em: " + count); for (int cc = count; cc > 0; cc--) { sResult += "\t"; } try { sResult += xmlString.substring(0, xmlString.indexOf("<")) + "\n"; xmlString = xmlString.substring(xmlString.indexOf("<")); sResult += displayXML(xmlString, count); } catch (Exception any) { //sResult += any; } } return sResult; } private static HttpURL uriToHttpURL(String uri) throws URIException { return uri.startsWith("https") ? new HttpsURL(uri) : new HttpURL(uri); } }