|
What this is
Other links
The source code/***************************************************************************** * Sun Public License Notice * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the CVS Client Library. * The Initial Developer of the Original Code is Robert Greig. * Portions created by Robert Greig are Copyright (C) 2000. * All Rights Reserved. * * Contributor(s): Robert Greig. *****************************************************************************/ package org.netbeans.lib.cvsclient.commandLine; import java.io.*; import java.text.MessageFormat; import java.util.Arrays; import java.util.Comparator; import java.util.ResourceBundle; import org.netbeans.lib.cvsclient.*; import org.netbeans.lib.cvsclient.CVSRoot; import org.netbeans.lib.cvsclient.admin.*; import org.netbeans.lib.cvsclient.command.*; import org.netbeans.lib.cvsclient.commandLine.command.CommandProvider; import org.netbeans.lib.cvsclient.connection.*; import org.netbeans.lib.cvsclient.connection.StandardScrambler; import org.netbeans.lib.cvsclient.event.CVSListener; /** * An implementation of the standard CVS client utility (command line tool) * in Java * @author Robert Greig */ public class CVSCommand { private static final String HELP_OPTIONS = "--help-options"; // NOI18N private static final String HELP_COMMANDS = "--help-commands"; // NOI18N private static final String HELP_SYNONYMS = "--help-synonyms"; // NOI18N /** * The path to the repository on the server */ private String repository; /** * The local path to use to perform operations (the top level) */ private String localPath; /** * The connection to the server */ private Connection connection; /** * The client that manages interactions with the server */ private Client client; /** * The global options being used. GlobalOptions are only global for a * particular command. */ private GlobalOptions globalOptions; /** * The port number that is used to connect to the remote server. * It is taken into account only when it's value is greater then zero. */ private int port = 0; /** * Execute a configured CVS command * @param command the command to execute * @throws CommandException if there is an error running the command */ public boolean executeCommand(Command command) throws CommandException, AuthenticationException { return client.executeCommand(command, globalOptions); } public void setRepository(String repository) { this.repository = repository; } public void setLocalPath(String localPath) { this.localPath = localPath; } public void setGlobalOptions(GlobalOptions globalOptions) { this.globalOptions = globalOptions; } /** * Creates the connection and the client and connects. */ private void connect(CVSRoot root, String password) throws IllegalArgumentException, AuthenticationException, CommandAbortedException { connection = ConnectionFactory.getConnection(root); if (CVSRoot.METHOD_PSERVER.equals(root.getMethod())) { ((PServerConnection) connection).setEncodedPassword(password); if (port > 0) ((PServerConnection) connection).setPort(port); } connection.open(); client = new Client(connection, new StandardAdminHandler()); client.setLocalPath(localPath); } private void addListener(CVSListener listener) { if (client != null) { // add a listener to the client client.getEventManager().addCVSListener(listener); } } private void close(PrintStream stderr) { try { connection.close(); } catch (IOException e) { stderr.println("Unable to close connection: " + e); //e.printStackTrace(); } } /** * Obtain the CVS root, either from the -D option cvs.root or from * the CVS directory * @return the CVSRoot string */ private static String getCVSRoot(String workingDir) { String root = null; BufferedReader r = null; if (workingDir == null) { workingDir = System.getProperty("user.dir"); } try { File f = new File(workingDir); File rootFile = new File(f, "CVS/Root"); if (rootFile.exists()) { r = new BufferedReader(new FileReader(rootFile)); root = r.readLine(); } } catch (IOException e) { // ignore } finally { try { if (r != null) r.close(); } catch (IOException e) { System.err.println("Warning: could not close CVS/Root file!"); } } if (root == null) { root = System.getProperty("cvs.root"); } return root; } /** * Process global options passed into the application * @param args the argument list, complete * @param globalOptions the global options structure that will be passed * to the command */ private static int processGlobalOptions(String[] args, GlobalOptions globalOptions, PrintStream stderr) { final String getOptString = globalOptions.getOptString(); GetOpt go = new GetOpt(args, getOptString); int ch = -1; boolean usagePrint = false; while ((ch = go.getopt()) != go.optEOF) { //System.out.println("Global option '"+((char) ch)+"', '"+go.optArgGet()+"'"); boolean success = globalOptions.setCVSCommand((char) ch, go.optArgGet()); if (!success) usagePrint = true; } if (usagePrint) { showUsage(stderr); return -10; } return go.optIndexGet(); } private static void showUsage(PrintStream stderr) { String usageStr = ResourceBundle.getBundle(CVSCommand.class.getPackage().getName()+".Bundle").getString("MSG_HelpUsage"); // NOI18N stderr.println(MessageFormat.format(usageStr, new Object[] { HELP_OPTIONS, HELP_COMMANDS, HELP_SYNONYMS })); //stderr.println("Usage: cvs [global options] command [command-options-and-arguments]"); //stderr.println(" specify "+HELP_OPTIONS+" for a list of options"); //stderr.println(" specify "+HELP_COMMANDS+" for a list of commands"); //stderr.println(" specify "+HELP_SYNONYMS+" for a list of command synonyms"); } /** * Perform the 'login' command, asking the user for a password. If the * login is successful, the password is written to a file. The file's * location is user.home, unless the cvs.passfile option is set. * @param userName the userName * @param hostName the host */ private static boolean performLogin(String userName, String hostName, String repository, int port, GlobalOptions globalOptions) { PServerConnection c = new PServerConnection(); c.setUserName(userName); String password = null; try { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Enter password: "); password = in.readLine(); } catch (IOException e) { System.err.println("Could not read password: " + e); return false; } String encodedPassword = StandardScrambler.getInstance().scramble( password); c.setEncodedPassword(encodedPassword); c.setHostName(hostName); c.setRepository(repository); c.setPort(port); try { c.verify(); } catch (AuthenticationException e) { System.err.println("Could not login to host " + hostName); return false; } // was successful, so write the appropriate file out // we look for cvs.passfile being set, but if not use user.dir // as the default File passFile = new File(System.getProperty("cvs.passfile", System.getProperty("user.home") + "/.cvspass")); BufferedWriter writer = null; BufferedReader reader = null; try { if (passFile.createNewFile()) { writer = new BufferedWriter(new FileWriter(passFile)); writer.write(globalOptions.getCVSRoot() + " " + encodedPassword); writer.close(); } else { File tempFile = File.createTempFile("cvs", "tmp", globalOptions.getTempDir()); reader = new BufferedReader(new FileReader(passFile)); writer = new BufferedWriter(new FileWriter(tempFile)); String line; while ((line = reader.readLine()) != null) { if (line.startsWith(globalOptions.getCVSRoot())) { writer.write(globalOptions.getCVSRoot() + " " + encodedPassword); } else { writer.write(line); } } reader.close(); writer.close(); File temp2File = File.createTempFile("cvs", "tmp", globalOptions.getTempDir()); passFile.renameTo(temp2File); tempFile.renameTo(passFile); temp2File.delete(); tempFile.delete(); } } catch (IOException e) { System.err.println("Error: could not write password file to " + passFile); return false; } finally { try { if (writer != null) { writer.close(); } if (reader != null) { reader.close(); } } catch (Exception e) { // ignore } } System.err.println("Logged in successfully to repository " + repository + " on host " + hostName); return true; } /** * Lookup the password in the .cvspass file. This file is looked for * in the user.home directory if the option cvs.passfile is not set * @param CVSRoot the CVS root for which the password is being searched * @return the password, scrambled */ private static String lookupPassword(String CVSRoot, String CVSRootWithPort, PrintStream stderr) { File passFile = new File(System.getProperty("cvs.passfile", System.getProperty("user.home") + "/.cvspass")); BufferedReader reader = null; String password = null; try { reader = new BufferedReader(new FileReader(passFile)); String line; while ((line = reader.readLine()) != null) { if (line.startsWith("/1 ")) line = line.substring("/1 ".length()); if (line.startsWith(CVSRoot+" ")) { password = line.substring(CVSRoot.length() + 1); break; } else if (line.startsWith(CVSRootWithPort+" ")) { password = line.substring(CVSRootWithPort.length() + 1); break; } } } catch (IOException e) { stderr.println("Could not read password for host: " + e); return null; } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { stderr.println("Warning: could not close password file."); } } } if (password == null) { stderr.println("Didn't find password for CVSROOT '"+CVSRoot+"'."); } return password; } /** * Execute the CVS command and exit JVM. */ public static void main(String[] args) { if (processCommand(args, null, System.getProperty("user.dir"), System.out, System.err)) { System.exit(0); } else { System.exit(1); } } /** * Process the CVS command passed in args[] array with all necessary options. * The only difference from main() method is, that this method does not exit * the JVM and provides command output. * @param args The command with options * @param files The files to execute the command on. * @param localPath The local working directory * @param stdout The standard output of the command * @param stderr The error output of the command. */ public static boolean processCommand(String[] args, File[] files, String localPath, PrintStream stdout, PrintStream stderr) { return processCommand(args, files, localPath, 0, stdout, stderr); } /** * Process the CVS command passed in args[] array with all necessary options. * The only difference from main() method is, that this method does not exit * the JVM and provides command output. * @param args The command with options * @param files The files to execute the command on. * @param localPath The local working directory * @param port The port number that is used to connect to the remote server. * It is taken into account only when it's value is greater then zero. * @param stdout The standard output of the command * @param stderr The error output of the command. * @return whether the command was processed successfully */ public static boolean processCommand(String[] args, File[] files, String localPath, int port, PrintStream stdout, PrintStream stderr) { // Provide help if requested if (args.length > 0) { if (HELP_OPTIONS.equals(args[0])) { printHelpOptions(stdout); return true; } else if (HELP_COMMANDS.equals(args[0])) { printHelpCommands(stdout); return true; } else if (HELP_SYNONYMS.equals(args[0])) { printHelpSynonyms(stdout); return true; } } try { // Adjust the local path localPath = new File(localPath).getCanonicalPath(); } catch (IOException ioex) {} // Set up the CVSRoot. Note that it might still be null after this // call if the user has decided to set it with the -d command line // global option GlobalOptions globalOptions = new GlobalOptions(); globalOptions.setCVSRoot(getCVSRoot(localPath)); // Set up any global options specified. These occur before the // name of the command to run int commandIndex = -1; try { commandIndex = processGlobalOptions(args, globalOptions, stderr); if (commandIndex == -10) return true; } catch (IllegalArgumentException e) { stderr.println("Invalid argument: " + e); return false; } if (globalOptions.isShowHelp()) { printHelp(commandIndex, args, stdout, stderr); return true; } if (globalOptions.isShowVersion()) { printVersion(stdout, stderr); return true; } // if we don't have a CVS root by now, the user has messed up if (globalOptions.getCVSRoot() == null) { stderr.println("No CVS root is set. Use the cvs.root " + "property, e.g. java -Dcvs.root=\":pserver:user@host:/usr/cvs\"" + " or start the application in a directory containing a CVS subdirectory" + " or use the -d command switch."); return false; } // parse the CVS root into its constituent parts CVSRoot root = null; final String cvsRoot = globalOptions.getCVSRoot(); try { root = CVSRoot.parse(cvsRoot); } catch (IllegalArgumentException e) { stderr.println("Incorrect format for CVSRoot: " + cvsRoot + "\nThe correct format is: "+ "[:method:][[user][:password]@][hostname:[port]]/path/to/repository" + "\nwhere \"method\" is pserver."); return false; } // if we had some options without any command, then the user messed up if (commandIndex >= args.length) { showUsage(stderr); return false; } final String command = args[commandIndex]; if (command.equals("login")) { if (CVSRoot.METHOD_PSERVER.equals(root.getMethod())) { return performLogin(root.getUserName(), root.getHostName(), root.getRepository(), root.getPort(), globalOptions); } else { stderr.println("login does not apply for connection type " + "\'" + root.getMethod() + "\'"); return false; } } // this is not login, but a 'real' cvs command, so construct it, // set the options, and then connect to the server and execute it Command c = null; try { c = CommandFactory.getDefault().createCommand(command, args, ++commandIndex, globalOptions, localPath); } catch (IllegalArgumentException e) { stderr.println("Illegal argument: " + e.getMessage()); return false; } if (files != null && c instanceof BasicCommand) { ((BasicCommand) c).setFiles(files); } String password = null; if (CVSRoot.METHOD_PSERVER.equals(root.getMethod())) { password = root.getPassword(); if (password != null) { password = StandardScrambler.getInstance().scramble(password); } else { if (port > 0) root.setPort(port); password = lookupPassword(cvsRoot, root.toString(), stderr); if (password == null) { password = StandardScrambler.getInstance().scramble(""); // an empty password } } } CVSCommand cvsCommand = new CVSCommand(); cvsCommand.setGlobalOptions(globalOptions); cvsCommand.setRepository(root.getRepository()); if (port > 0) { cvsCommand.port = port; } // the local path is just the path where we executed the // command. This is the case for command-line CVS but not // usually for GUI front-ends cvsCommand.setLocalPath(localPath); try { cvsCommand.connect(root, password); CVSListener list; if (c instanceof ListenerProvider) { list = ((ListenerProvider)c).createCVSListener(stdout, stderr); } else { list = new BasicListener(stdout, stderr); } cvsCommand.addListener(list); boolean status = cvsCommand.executeCommand(c); return status; } catch (AuthenticationException aex) { stderr.println(aex.getLocalizedMessage()); return false; } catch (CommandAbortedException caex) { stderr.println("Error: " + caex); Thread.currentThread().interrupt(); return false; } catch (Exception t) { stderr.println("Error: " + t); t.printStackTrace(stderr); return false; } finally { if (cvsCommand != null) { cvsCommand.close(stderr); } } } private static void printHelpOptions(PrintStream stdout) { String options = ResourceBundle.getBundle(CVSCommand.class.getPackage().getName()+".Bundle").getString("MSG_HelpOptions"); // NOI18N stdout.println(options); } private static void printHelpCommands(PrintStream stdout) { String msg = ResourceBundle.getBundle(CVSCommand.class.getPackage().getName()+".Bundle").getString("MSG_CVSCommands"); // NOI18N stdout.println(msg); CommandProvider[] providers = CommandFactory.getDefault().getCommandProviders(); Arrays.sort(providers, new CommandProvidersComparator()); int maxNameLength = 0; for (int i = 0; i < providers.length; i++) { int l = providers[i].getName().length(); if (maxNameLength < l) { maxNameLength = l; } } maxNameLength += 2; // Two spaces from the longest name for (int i = 0; i < providers.length; i++) { stdout.print("\t"+providers[i].getName()); char spaces[] = new char[maxNameLength - providers[i].getName().length()]; Arrays.fill(spaces, ' '); stdout.print(new String(spaces)); providers[i].printShortDescription(stdout); stdout.println(); } } private static void printHelpSynonyms(PrintStream stdout) { String msg = ResourceBundle.getBundle(CVSCommand.class.getPackage().getName()+".Bundle").getString("MSG_CVSSynonyms"); // NOI18N stdout.println(msg); CommandProvider[] providers = CommandFactory.getDefault().getCommandProviders(); Arrays.sort(providers, new CommandProvidersComparator()); int maxNameLength = 0; for (int i = 0; i < providers.length; i++) { int l = providers[i].getName().length(); if (maxNameLength < l) { maxNameLength = l; } } maxNameLength += 2; // Two spaces from the longest name for (int i = 0; i < providers.length; i++) { String[] synonyms = providers[i].getSynonyms(); if (synonyms.length > 0) { stdout.print("\t"+providers[i].getName()); char spaces[] = new char[maxNameLength - providers[i].getName().length()]; Arrays.fill(spaces, ' '); stdout.print(new String(spaces)); for (int j = 0; j < synonyms.length; j++) { stdout.print(synonyms[j]+" "); } stdout.println(); } } } private static void printHelp(int commandIndex, String[] args, PrintStream stdout, PrintStream stderr) { if (commandIndex >= args.length) { showUsage(stdout); } else { String cmdName = args[commandIndex]; CommandProvider provider = CommandFactory.getDefault().getCommandProvider(cmdName); if (provider == null) { printUnknownCommand(cmdName, stderr); } else { provider.printLongDescription(stdout); } } } private static void printVersion(PrintStream stdout, PrintStream stderr) { String version = CVSCommand.class.getPackage().getSpecificationVersion(); stdout.println("Java Concurrent Versions System (JavaCVS) "+version+" (client)"); } private static void printUnknownCommand(String commandName, PrintStream out) { String msg = ResourceBundle.getBundle(CVSCommand.class.getPackage().getName()+".Bundle").getString("MSG_UnknownCommand"); // NOI18N out.println(MessageFormat.format(msg, new Object[] { commandName })); printHelpCommands(out); } private static final class CommandProvidersComparator implements Comparator { public int compare(Object o1, Object o2) { if (!(o1 instanceof CommandProvider) || !(o2 instanceof CommandProvider)) { throw new IllegalArgumentException("Can not compare objects "+o1+" and "+o2); } return ((CommandProvider) o1).getName().compareTo(((CommandProvider) o2).getName()); } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.