Source Code Cross Referenced for Client.java in  » IDE-Netbeans » cvsclient » org » netbeans » lib » cvsclient » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » cvsclient » org.netbeans.lib.cvsclient 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*****************************************************************************
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is the CVS Client Library.
0027:         * The Initial Developer of the Original Software is Robert Greig.
0028:         * Portions created by Robert Greig are Copyright (C) 2000.
0029:         * All Rights Reserved.
0030:         *
0031:         * If you wish your version of this file to be governed by only the CDDL
0032:         * or only the GPL Version 2, indicate your decision by adding
0033:         * "[Contributor] elects to include this software in this distribution
0034:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0035:         * single choice of license, a recipient has the option to distribute
0036:         * your version of this file under either the CDDL, the GPL Version 2 or
0037:         * to extend the choice of license to its licensees as provided above.
0038:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0039:         * Version 2 license, then the option applies only if the new code is
0040:         * made subject to such option by the copyright holder.
0041:         *
0042:         * Contributor(s): Robert Greig.
0043:         *****************************************************************************/package org.netbeans.lib.cvsclient;
0044:
0045:        import java.io.*;
0046:        import java.util.*;
0047:
0048:        import org.netbeans.lib.cvsclient.admin.*;
0049:        import org.netbeans.lib.cvsclient.command.*;
0050:        import org.netbeans.lib.cvsclient.connection.*;
0051:        import org.netbeans.lib.cvsclient.event.*;
0052:        import org.netbeans.lib.cvsclient.file.*;
0053:        import org.netbeans.lib.cvsclient.request.*;
0054:        import org.netbeans.lib.cvsclient.response.*;
0055:        import org.netbeans.lib.cvsclient.util.*;
0056:
0057:        /**
0058:         * The main way of communication with a server using the CVS Protocol. The
0059:         * client is not responsible for setting up the connection with the server,
0060:         * only interacting with it.
0061:         * @see org.netbeans.lib.cvsclient.connection.Connection
0062:         * @author  Robert Greig
0063:         */
0064:        public class Client implements  ClientServices, ResponseServices {
0065:            /**
0066:             * The connection used to interact with the server.
0067:             */
0068:            private Connection connection;
0069:
0070:            /**
0071:             * The file handler to use.
0072:             */
0073:            private FileHandler transmitFileHandler;
0074:
0075:            private FileHandler gzipFileHandler = new GzippedFileHandler();
0076:            private FileHandler uncompFileHandler = new DefaultFileHandler();
0077:
0078:            private boolean dontUseGzipFileHandler;
0079:
0080:            /**
0081:             * The modified date.
0082:             */
0083:            private Date modifiedDate;
0084:
0085:            /**
0086:             * The admin handler to use.
0087:             */
0088:            private AdminHandler adminHandler;
0089:
0090:            /**
0091:             * The local path, ie the path to the directory in which this command
0092:             * was executed.
0093:             */
0094:            private String localPath;
0095:
0096:            /**
0097:             * Whether any commands have been executed so far. This allows us to
0098:             * send some initialisation requests before the first command.
0099:             */
0100:            private boolean isFirstCommand = true;
0101:
0102:            /**
0103:             * The event manager.
0104:             */
0105:            private final EventManager eventManager = new EventManager(this );
0106:
0107:            /**
0108:             * The global options for the executing command.
0109:             */
0110:            private GlobalOptions globalOptions;
0111:
0112:            private PrintStream stderr = System.err;
0113:
0114:            /**
0115:             * This is set to true if we should abort the current command.
0116:             */
0117:            private boolean abort;
0118:
0119:            private ResponseFactory responseFactory;
0120:
0121:            private IgnoreFileFilter ignoreFileFilter;
0122:
0123:            /*
0124:             * The valid list of requests that is valid for the CVS server
0125:             * corresponding to this client
0126:             */
0127:            private Map validRequests = new HashMap();
0128:
0129:            /**
0130:             * A map of file patterns and keyword substitution options
0131:             */
0132:            private Map wrappersMap = null;
0133:
0134:            /**
0135:             * This will be set to true after initialization requests are sent
0136:             * to the server. The initialization requests setup valid requests
0137:             * and send RootRequest to the server.
0138:             */
0139:            private boolean initialRequestsSent = false;
0140:
0141:            private boolean printConnectionReuseWarning = false;
0142:
0143:            private static final Set ALLOWED_CONNECTION_REUSE_REQUESTS = new HashSet(
0144:                    Arrays.asList(new Class[] { ExpandModulesRequest.class,
0145:                            WrapperSendRequest.class }));
0146:
0147:            // processRequests &  getCounter
0148:            private LoggedDataInputStream loggedDataInputStream;
0149:            private LoggedDataOutputStream loggedDataOutputStream;
0150:            private boolean warned;
0151:
0152:            /**
0153:             * Construct a Client using a given connection and file handler.
0154:             * You must initialize the connection and adminHandler first.
0155:             * <code>
0156:             *  // establish connection to the given CVS pserver
0157:             *  PServerConnection connection = new PServerConnection();
0158:             *  connection.setUserName(userName);
0159:             *  connection.setHostName(hostName);
0160:             *  connection.setEncodedPassword(StandardScrambler.getInstance().scramble(password));
0161:             *  connection.setRepository(repository);
0162:             *  // test the connection
0163:             *  try {
0164:             *      connection.open();
0165:             *  } catch (AuthenticationException e) {
0166:             *      // do something
0167:             *  }
0168:             *
0169:             *  // create a CVS client
0170:             *  Client cvsClient = new Client(connection,new StandardAdminHandler());
0171:             *
0172:             *  // set the directory in which we work
0173:             *  cvsClient.setLocalPath(localPath);
0174:             * </code>
0175:             * @param connection the connection to the cvs server
0176:             * @param adminHandler the admin handler to use
0177:             */
0178:            public Client(Connection connection, AdminHandler adminHandler) {
0179:                setConnection(connection);
0180:                setAdminHandler(adminHandler);
0181:                ignoreFileFilter = new DefaultIgnoreFileFilter();
0182:                dontUseGzipFileHandler = false;
0183:            }
0184:
0185:            public void setErrorStream(PrintStream stderr) {
0186:                this .stderr = stderr;
0187:            }
0188:
0189:            /**
0190:             * Get the connection used for communicating with the server.
0191:             * Connection.
0192:             * @return the connection
0193:             */
0194:            public Connection getConnection() {
0195:                return connection;
0196:            }
0197:
0198:            /**
0199:             * Set the connection used for communicating with the server.
0200:             * @param c the connection to use for all communication with the server
0201:             */
0202:            public void setConnection(Connection connection) {
0203:                this .connection = connection;
0204:                initialRequestsSent = false;
0205:                setIsFirstCommand(true);
0206:            }
0207:
0208:            /**
0209:             * Get the admin handler uesd to read and write administrative information
0210:             * about files on the local machine.
0211:             * @return the admin handler
0212:             */
0213:            public AdminHandler getAdminHandler() {
0214:                return adminHandler;
0215:            }
0216:
0217:            /**
0218:             * Set the admin handler used to read and write administrative information
0219:             * about files on the local machine.
0220:             */
0221:            public void setAdminHandler(AdminHandler adminHandler) {
0222:                this .adminHandler = adminHandler;
0223:            }
0224:
0225:            /**
0226:             * Get the local path; that is, the path to the directory in which
0227:             * the currently executing command is referring.
0228:             */
0229:            public String getLocalPath() {
0230:                return localPath;
0231:            }
0232:
0233:            /**
0234:             * Set the local path, i.e. the path to the directory in which all
0235:             * commands are given (top level).
0236:             */
0237:            public void setLocalPath(String localPath) {
0238:                // remove trailing (back-) slash
0239:                localPath = localPath.replace('\\', '/');
0240:                while (localPath.endsWith("/")) { // NOI18N
0241:                    localPath = localPath.substring(0, localPath.length() - 1);
0242:                }
0243:
0244:                this .localPath = localPath;
0245:            }
0246:
0247:            /**
0248:             * Returns true if no previous command was executed using thiz.
0249:             */
0250:            public boolean isFirstCommand() {
0251:                return isFirstCommand;
0252:            }
0253:
0254:            /**
0255:             * Set whether this is the first command. Normally you do not need to set
0256:             * this yourself - after execution the first command will have set this to
0257:             * false.
0258:             */
0259:            public void setIsFirstCommand(boolean isFirstCommand) {
0260:                this .isFirstCommand = isFirstCommand;
0261:            }
0262:
0263:            /**
0264:             * Return the uncompressed file handler.
0265:             */
0266:            public FileHandler getUncompressedFileHandler() {
0267:                return uncompFileHandler;
0268:            }
0269:
0270:            /**
0271:             * Set the uncompressed file handler.
0272:             */
0273:            public void setUncompressedFileHandler(FileHandler uncompFileHandler) {
0274:                this .uncompFileHandler = uncompFileHandler;
0275:            }
0276:
0277:            /**
0278:             * Return the Gzip stream handler.
0279:             */
0280:            public FileHandler getGzipFileHandler() {
0281:                return gzipFileHandler;
0282:            }
0283:
0284:            /**
0285:             * Set the handler for Gzip data.
0286:             */
0287:            public void setGzipFileHandler(FileHandler gzipFileHandler) {
0288:                this .gzipFileHandler = gzipFileHandler;
0289:            }
0290:
0291:            /**
0292:             * ReSet the filehandler for Gzip compressed data. Makes sure the
0293:             * requests for sending gzipped data are not sent..
0294:             */
0295:            public void dontUseGzipFileHandler() {
0296:                setGzipFileHandler(new DefaultFileHandler());
0297:                dontUseGzipFileHandler = true;
0298:            }
0299:
0300:            public boolean isAborted() {
0301:                return abort;
0302:            }
0303:
0304:            /**
0305:             * Ensures, that the connection is open.
0306:             *
0307:             * @throws AuthenticationException if it wasn't possible to connect
0308:             */
0309:            public void ensureConnection() throws AuthenticationException {
0310:                BugLog.getInstance().assertNotNull(getConnection());
0311:
0312:                if (getConnection().isOpen()) {
0313:                    return;
0314:                }
0315:
0316:                // #69689 detect silent servers, possibly caused by proxy errors
0317:                final Throwable ex[] = new Throwable[1];
0318:                final boolean opened[] = new boolean[] { false };
0319:                Runnable probe = new Runnable() {
0320:                    public void run() {
0321:                        try {
0322:                            getConnection().open();
0323:                            synchronized (opened) {
0324:                                opened[0] = true;
0325:                            }
0326:                        } catch (Throwable e) {
0327:                            synchronized (ex) {
0328:                                ex[0] = e;
0329:                            }
0330:                        }
0331:                    }
0332:                };
0333:
0334:                Thread probeThread = new Thread(probe, "CVS Server Probe"); // NOI18N
0335:                probeThread.start();
0336:                try {
0337:
0338:                    probeThread.join(60 * 1000); // 1 min
0339:
0340:                    Throwable wasEx;
0341:                    synchronized (ex) {
0342:                        wasEx = ex[0];
0343:                    }
0344:                    if (wasEx != null) {
0345:                        if (wasEx instanceof  CommandAbortedException) {
0346:                            // User cancelled
0347:                            abort();
0348:                            return;
0349:                        } else if (wasEx instanceof  AuthenticationException) {
0350:                            throw (AuthenticationException) wasEx;
0351:                        } else if (wasEx instanceof  RuntimeException) {
0352:                            throw (RuntimeException) wasEx;
0353:                        } else if (wasEx instanceof  Error) {
0354:                            throw (Error) wasEx;
0355:                        } else {
0356:                            assert false : wasEx;
0357:                        }
0358:                    }
0359:
0360:                    boolean wasOpened;
0361:                    synchronized (opened) {
0362:                        wasOpened = opened[0];
0363:                    }
0364:                    if (wasOpened == false) {
0365:                        probeThread.interrupt();
0366:                        throw new AuthenticationException(
0367:                                "Timeout, no response from server.",
0368:                                "Timeout, no response from server.");
0369:                    }
0370:
0371:                } catch (InterruptedException e) {
0372:
0373:                    // User cancelled
0374:                    probeThread.interrupt();
0375:                    abort();
0376:                }
0377:            }
0378:
0379:            /**
0380:             * Process all the requests. The connection must have been opened and
0381:             * set first.
0382:             * @param requests the requets to process
0383:             */
0384:            public void processRequests(List requests) throws IOException,
0385:                    UnconfiguredRequestException, ResponseException,
0386:                    CommandAbortedException {
0387:
0388:                if (requests == null || requests.size() == 0) {
0389:                    throw new IllegalArgumentException(
0390:                            "[processRequests] requests " + // NOI18N
0391:                                    "was either null or empty."); // NOI18N
0392:                }
0393:
0394:                if (abort) {
0395:                    throw new CommandAbortedException(
0396:                            "Aborted during request processing", // NOI18N
0397:                            CommandException.getLocalMessage(
0398:                                    "Client.commandAborted", null)); //NOI18N
0399:                }
0400:
0401:                loggedDataInputStream = null;
0402:                loggedDataOutputStream = null;
0403:
0404:                // send the initialisation requests if we are handling the first
0405:                // command
0406:                boolean filterRootRequest = true;
0407:                if (isFirstCommand()) {
0408:                    setIsFirstCommand(false);
0409:                    int pos = 0;
0410:                    if (!initialRequestsSent) {
0411:                        pos = fillInitialRequests(requests);
0412:                        initialRequestsSent = true;
0413:                        filterRootRequest = false;
0414:                    }
0415:                    if (globalOptions != null) {
0416:                        // sends the global options that are to be sent to server (-q, -Q, -t, -n, l)
0417:                        for (Iterator it = globalOptions.createRequestList()
0418:                                .iterator(); it.hasNext();) {
0419:                            Request request = (Request) it.next();
0420:                            requests.add(pos++, request);
0421:                        }
0422:
0423:                        if (globalOptions.isUseGzip()
0424:                                && globalOptions.getCompressionLevel() != 0) {
0425:                            requests.add(pos++, new GzipFileContentsRequest(
0426:                                    globalOptions.getCompressionLevel()));
0427:                        }
0428:                    }
0429:                } else if (printConnectionReuseWarning) {
0430:                    if (System.getProperty("javacvs.multiple_commands_warning") == null) { //NOI18N
0431:                        System.err.println("WARNING TO DEVELOPERS:"); //NOI18N
0432:                        System.err
0433:                                .println("Please be warned that attempting to reuse one open connection for more commands is not supported by cvs servers very well."); //NOI18N
0434:                        System.err
0435:                                .println("You are advised to open a new Connection each time."); //NOI18N
0436:                        System.err
0437:                                .println("If you still want to proceed, please do: System.setProperty(\"javacvs.multiple_commands_warning\", \"false\")"); //NOI18N
0438:                        System.err.println("That will disable this message."); //NOI18N
0439:                    }
0440:                }
0441:
0442:                if (!ALLOWED_CONNECTION_REUSE_REQUESTS.contains(requests.get(
0443:                        requests.size() - 1).getClass())) {
0444:                    printConnectionReuseWarning = true;
0445:                }
0446:
0447:                final boolean fireEnhancedEvents = getEventManager()
0448:                        .isFireEnhancedEventSet();
0449:                int fileDetailRequestCount = 0;
0450:
0451:                if (fireEnhancedEvents) {
0452:                    for (Iterator it = requests.iterator(); it.hasNext();) {
0453:                        Request request = (Request) it.next();
0454:
0455:                        FileDetails fileDetails = request
0456:                                .getFileForTransmission();
0457:                        if (fileDetails != null
0458:                                && fileDetails.getFile().exists()) {
0459:                            fileDetailRequestCount++;
0460:                        }
0461:                    }
0462:                    CVSEvent event = new EnhancedMessageEvent(this ,
0463:                            EnhancedMessageEvent.REQUESTS_COUNT, new Integer(
0464:                                    fileDetailRequestCount));
0465:                    getEventManager().fireCVSEvent(event);
0466:                }
0467:
0468:                LoggedDataOutputStream dos = connection.getOutputStream();
0469:                loggedDataOutputStream = dos;
0470:
0471:                // this list stores stream modification requests, each to be called
0472:                // to modify the input stream the next time we need to process a
0473:                // response
0474:                List streamModifierRequests = new LinkedList();
0475:
0476:                // sending files does not seem to allow compression
0477:                transmitFileHandler = getUncompressedFileHandler();
0478:
0479:                for (Iterator it = requests.iterator(); it.hasNext();) {
0480:                    if (abort) {
0481:                        throw new CommandAbortedException(
0482:                                "Aborted during request processing", // NOI18N
0483:                                CommandException.getLocalMessage(
0484:                                        "Client.commandAborted", null)); //NOI18N
0485:                    }
0486:
0487:                    final Request request = (Request) it.next();
0488:
0489:                    if (request instanceof  GzipFileContentsRequest) {
0490:                        if (dontUseGzipFileHandler) {
0491:                            stderr
0492:                                    .println("Warning: The server is not supporting gzip-file-contents request, no compression is used.");
0493:                            continue;
0494:                        }
0495:                    }
0496:
0497:                    // skip the root request if already sent
0498:                    if (request instanceof  RootRequest) {
0499:                        if (filterRootRequest) {
0500:                            continue;
0501:                        } else { // Even if we should not filter the RootRequest now, we must filter all successive RootRequests
0502:                            filterRootRequest = true;
0503:                        }
0504:                    }
0505:                    // send request to server
0506:                    String requestString = request.getRequestString();
0507:                    dos.writeBytes(requestString);
0508:
0509:                    // we must modify the outputstream now, but defer modification
0510:                    // of the inputstream until we are about to read a response.
0511:                    // This is because some modifiers (e.g. gzip) read the header
0512:                    // on construction, and obviously no header is present when
0513:                    // no response has been sent
0514:                    request.modifyOutputStream(connection);
0515:                    if (request.modifiesInputStream()) {
0516:                        streamModifierRequests.add(request);
0517:                    }
0518:                    dos = connection.getOutputStream();
0519:
0520:                    FileDetails fileDetails = request.getFileForTransmission();
0521:                    if (fileDetails != null) {
0522:                        final File file = fileDetails.getFile();
0523:                        // only transmit the file if it exists! When committing
0524:                        // a remove request you cannot transmit the file
0525:                        if (file.exists()) {
0526:                            Logger.logOutput(new String("<Sending file: " + // NOI18N
0527:                                    file.getAbsolutePath() + ">\n")
0528:                                    .getBytes("utf8")); // NOI18N
0529:
0530:                            if (fireEnhancedEvents) {
0531:                                CVSEvent event = new EnhancedMessageEvent(this ,
0532:                                        EnhancedMessageEvent.FILE_SENDING, file);
0533:                                getEventManager().fireCVSEvent(event);
0534:
0535:                                fileDetailRequestCount--;
0536:                            }
0537:
0538:                            if (fileDetails.isBinary()) {
0539:                                transmitFileHandler.transmitBinaryFile(file,
0540:                                        dos);
0541:                            } else {
0542:                                transmitFileHandler.transmitTextFile(file, dos);
0543:                            }
0544:
0545:                            if (fireEnhancedEvents
0546:                                    && fileDetailRequestCount == 0) {
0547:                                CVSEvent event = new EnhancedMessageEvent(this ,
0548:                                        EnhancedMessageEvent.REQUESTS_SENT,
0549:                                        "Ok"); // NOI18N
0550:                                getEventManager().fireCVSEvent(event);
0551:                            }
0552:                        }
0553:                    }
0554:                    if (request.isResponseExpected()) {
0555:                        dos.flush();
0556:
0557:                        // now perform the deferred modification of the input stream
0558:                        Iterator modifiers = streamModifierRequests.iterator();
0559:                        while (modifiers.hasNext()) {
0560:                            System.err.println("Modifying the inputstream..."); // NOI18N
0561:                            final Request smRequest = (Request) modifiers
0562:                                    .next();
0563:                            System.err.println("Request is a: " + // NOI18N
0564:                                    smRequest.getClass().getName());
0565:                            smRequest.modifyInputStream(connection);
0566:                        }
0567:                        streamModifierRequests.clear();
0568:
0569:                        handleResponse();
0570:                    }
0571:                }
0572:                dos.flush();
0573:
0574:                transmitFileHandler = null;
0575:            }
0576:
0577:            private ResponseFactory getResponseFactory() {
0578:                if (responseFactory == null) {
0579:                    responseFactory = new ResponseFactory();
0580:                }
0581:                return responseFactory;
0582:            }
0583:
0584:            /**
0585:             * Handle the response from a request.
0586:             * @throws ResponseException if there is a problem reading the response
0587:             */
0588:            private void handleResponse() throws ResponseException,
0589:                    CommandAbortedException {
0590:                try {
0591:                    LoggedDataInputStream dis = connection.getInputStream();
0592:                    loggedDataInputStream = dis;
0593:
0594:                    int ch = -1;
0595:                    try {
0596:                        ch = dis.read();
0597:                    } catch (InterruptedIOException ex) {
0598:                        abort();
0599:                    }
0600:
0601:                    while (!abort && ch != -1) {
0602:                        StringBuffer responseNameBuffer = new StringBuffer();
0603:                        // read in the response name
0604:                        while (ch != -1 && (char) ch != '\n'
0605:                                && (char) ch != ' ') {
0606:                            responseNameBuffer.append((char) ch);
0607:                            try {
0608:                                ch = dis.read();
0609:                            } catch (InterruptedIOException ex) {
0610:                                abort();
0611:                                break;
0612:                            }
0613:                        }
0614:
0615:                        String responseString = responseNameBuffer.toString();
0616:                        Response response = getResponseFactory()
0617:                                .createResponse(responseString);
0618:                        //Logger.logInput(new String("<" + responseString + " processing start>\n").getBytes()); // NOI18N
0619:                        response.process(dis, this );
0620:                        boolean terminal = response.isTerminalResponse();
0621:
0622:                        // handle SpecialResponses
0623:                        if (terminal
0624:                                && response instanceof  ErrorMessageResponse) {
0625:                            ErrorMessageResponse errorResponce = (ErrorMessageResponse) response;
0626:                            String errMsg = errorResponce.getMessage();
0627:                            throw new CommandAbortedException(errMsg, errMsg);
0628:                        }
0629:                        //Logger.logInput(new String("<" + responseString + " processed " + terminal + ">\n").getBytes()); // NOI18N
0630:                        if (terminal || abort) {
0631:                            break;
0632:                        }
0633:
0634:                        try {
0635:                            ch = dis.read();
0636:                        } catch (InterruptedIOException ex) {
0637:                            abort();
0638:                            break;
0639:                        }
0640:                    }
0641:
0642:                    if (abort) {
0643:                        String localMsg = CommandException.getLocalMessage(
0644:                                "Client.commandAborted", null); //NOI18N
0645:                        throw new CommandAbortedException(
0646:                                "Aborted during request processing", localMsg); // NOI18N
0647:                    }
0648:                } catch (EOFException ex) {
0649:                    throw new ResponseException(ex,
0650:                            ResponseException.getLocalMessage(
0651:                                    "CommandException.EndOfFile", null)); //NOI18N
0652:                } catch (IOException ex) {
0653:                    throw new ResponseException(ex);
0654:                }
0655:            }
0656:
0657:            /**
0658:             * Execute a command. Do not forget to initialize the CVS Root on globalOptions first!
0659:             * Example:
0660:             * <code>
0661:             *   GlobalOptions options = new GlobalOptions();
0662:             *   options.setCVSRoot(":pserver:"+userName+"@"+hostName+":"+cvsRoot);
0663:             * </code>
0664:             * @param command the command to execute
0665:             * @param options the global options to use for executing the command
0666:             * @throws CommandException if an error occurs when executing the command
0667:             * @throws CommandAbortedException if the command is aborted
0668:             */
0669:            public boolean executeCommand(Command command,
0670:                    GlobalOptions globalOptions) throws CommandException,
0671:                    CommandAbortedException, AuthenticationException {
0672:                BugLog.getInstance().assertNotNull(command);
0673:                BugLog.getInstance().assertNotNull(globalOptions);
0674:
0675:                this .globalOptions = globalOptions;
0676:
0677:                getUncompressedFileHandler().setGlobalOptions(globalOptions);
0678:                getGzipFileHandler().setGlobalOptions(globalOptions);
0679:
0680:                try {
0681:                    eventManager.addCVSListener(command);
0682:                    command.execute(this , eventManager);
0683:                } finally {
0684:                    eventManager.removeCVSListener(command);
0685:                }
0686:                return !command.hasFailed();
0687:            }
0688:
0689:            /**
0690:             * Counts {@link #processRequests(java.util.List)}. send and received bytes.
0691:             *
0692:             * @thread it assumes that client is not run in paralel.
0693:             */
0694:            public long getCounter() {
0695:                long ret = 0;
0696:                if (loggedDataInputStream != null) {
0697:                    ret += loggedDataInputStream.getCounter();
0698:                }
0699:                if (loggedDataOutputStream != null) {
0700:                    ret += loggedDataOutputStream.getCounter();
0701:                }
0702:                return ret;
0703:            }
0704:
0705:            /**
0706:             * Convert a <i>pathname</i> in the CVS sense (see 5.10 in the protocol
0707:             * document) into a local absolute pathname for the file.
0708:             * @param localDirectory the name of the local directory, relative to the
0709:             * directory in which the command was given
0710:             * @param repository the full repository name for the file
0711:             */
0712:            public String convertPathname(String localDirectory,
0713:                    String repository) {
0714:                int lastIndexOfSlash = repository.lastIndexOf('/');
0715:                String filename = repository.substring(lastIndexOfSlash + 1);
0716:
0717:                if (localDirectory.startsWith("./")) { // NOI18N
0718:                    // remove the dot
0719:                    localDirectory = localDirectory.substring(1);
0720:                }
0721:                if (localDirectory.startsWith("/")) { // NOI18N
0722:                    // remove the leading slash
0723:                    localDirectory = localDirectory.substring(1);
0724:                }
0725:                // note that the localDirectory ends in a slash
0726:                return getLocalPath() + '/' + localDirectory + filename;
0727:            }
0728:
0729:            /**
0730:             * Get the repository path from the connection.
0731:             *
0732:             * @return the repository path, e.g. /home/bob/cvs. Delegated to the
0733:             * Connection in this case
0734:             * @see Connection#getRepository()
0735:             */
0736:            public String getRepository() {
0737:                return connection.getRepository();
0738:            }
0739:
0740:            /**
0741:             * Create or update the administration files for a particular file.
0742:             * This will create the CVS directory if necessary, and the
0743:             * Root and Repository files if necessary. It will also update
0744:             * the Entries file with the new entry
0745:             * @param localDirectory the local directory, relative to the directory
0746:             * in which the command was given, where the file in question lives
0747:             * @param repositoryPath the path of the file in the repository, in
0748:             * absolute form.
0749:             * @param entry the entry object for that file
0750:             */
0751:            public void updateAdminData(String localDirectory,
0752:                    String repositoryPath, Entry entry) throws IOException {
0753:                final String absolutePath = localPath + '/' + localDirectory;
0754:                if (repositoryPath.startsWith(getRepository())) {
0755:                    repositoryPath = repositoryPath.substring(getRepository()
0756:                            .length() + 1);
0757:                } else {
0758:                    if (warned == false) {
0759:                        String warning = "#65188 warning C/S protocol error (section 5.10). It's regurarly observed with cvs 1.12.xx servers.\n"; // NOI18N
0760:                        warning += "  unexpected pathname=" + repositoryPath
0761:                                + " missing root prefix=" + getRepository()
0762:                                + "\n"; // NOI18N
0763:                        warning += "  relaxing, but who knows all consequences...."; // NOI18N
0764:                        System.err.println(warning);
0765:                        warned = true;
0766:                    }
0767:                }
0768:
0769:                adminHandler.updateAdminData(absolutePath, repositoryPath,
0770:                        entry, globalOptions);
0771:            }
0772:
0773:            /**
0774:             * Set the modified date of the next file to be written. The next call
0775:             * to write<Type>File will use this date.
0776:             * @param modifiedDate the date the file should be marked as modified
0777:             */
0778:            public void setNextFileDate(Date modifiedDate) {
0779:                this .modifiedDate = modifiedDate;
0780:            }
0781:
0782:            /**
0783:             * Get the modified date for the next file.
0784:             * @return the date and then null the instance variable.
0785:             */
0786:            public Date getNextFileDate() {
0787:                //
0788:                // We null the instance variable so that future calls will not
0789:                // retrieve a date specified for a previous file
0790:                //
0791:                Date copy = modifiedDate;
0792:                modifiedDate = null;
0793:                return copy;
0794:            }
0795:
0796:            /**
0797:             * Get the Entry for the specified file, if one exists.
0798:             * @param f the file
0799:             * @throws IOException if the Entries file cannot be read
0800:             */
0801:            public Entry getEntry(File f) throws IOException {
0802:                return adminHandler.getEntry(f);
0803:            }
0804:
0805:            /**
0806:             * Get the entries for a specified directory.
0807:             * @param directory the directory for which to get the entries
0808:             * @return an iterator of Entry objects
0809:             */
0810:            public Iterator getEntries(File directory) throws IOException {
0811:                return adminHandler.getEntries(directory);
0812:            }
0813:
0814:            public boolean exists(File file) {
0815:                return adminHandler.exists(file);
0816:            }
0817:
0818:            /**
0819:             * Get the repository path for a given directory, for example in
0820:             * the directory /home/project/foo/bar, the repository directory
0821:             * might be /usr/cvs/foo/bar. The repository directory is commonly
0822:             * stored in the file <pre>Repository</pre> in the CVS directory on
0823:             * the client (this is the case in the standard CVS command-line tool).
0824:             *
0825:             * If no <pre>CVS/Repository</pre> file was found, the specified directory,
0826:             * the localpath are used to "guess" the repository path.
0827:             *
0828:             * @param directory the directory
0829:             */
0830:            public String getRepositoryForDirectory(String directory)
0831:                    throws IOException {
0832:                try {
0833:                    String repository = adminHandler.getRepositoryForDirectory(
0834:                            directory, getRepository());
0835:                    return repository;
0836:                } catch (IOException ex) {
0837:                    // an IOException is thrown, if the adminHandler can't detect the repository
0838:                    // by reading the CVS/Repository file, e.g. when checking out into a new directory
0839:                    try {
0840:                        directory = new File(directory).getCanonicalPath();
0841:                    } catch (IOException ioex) {
0842:                    }
0843:                    directory = directory.replace('\\', '/');
0844:                    while (directory.endsWith("/")) { // NOI18N
0845:                        directory = directory.substring(0,
0846:                                directory.length() - 1);
0847:                    }
0848:
0849:                    // must also canonicalize 'localPath' to be in sync with 'directory'
0850:                    String localPathCanonical = getLocalPath();
0851:                    try {
0852:                        localPathCanonical = new File(getLocalPath())
0853:                                .getCanonicalPath();
0854:                    } catch (IOException ioex) {
0855:                    }
0856:                    localPathCanonical = localPathCanonical.replace('\\', '/');
0857:                    while (localPathCanonical.endsWith("/")) { // NOI18N
0858:                        localPathCanonical = localPathCanonical.substring(0,
0859:                                localPathCanonical.length() - 1);
0860:                    }
0861:                    int localPathLength = localPathCanonical.length();
0862:
0863:                    String repository;
0864:                    if (directory.length() >= localPathLength) {
0865:                        repository = getRepository()
0866:                                + directory.substring(localPathLength);
0867:                    } else { // Asking for some folder upon the local working path
0868:                        repository = getRepository();
0869:                    }
0870:                    return repository;
0871:                }
0872:            }
0873:
0874:            public String getRepositoryForDirectory(File directory)
0875:                    throws IOException {
0876:                return adminHandler.getRepositoryForDirectory(directory
0877:                        .getAbsolutePath(), getRepository());
0878:            }
0879:
0880:            /**
0881:             * Set the Entry for the specified file.
0882:             * @param file the file
0883:             * @param entry the new entry
0884:             * @throws IOException if an error occurs writing the details
0885:             */
0886:            public void setEntry(File file, Entry entry) throws IOException {
0887:                adminHandler.setEntry(file, entry);
0888:            }
0889:
0890:            /**
0891:             * Remove the Entry for the specified file.
0892:             * @param file the file whose entry is to be removed
0893:             * @throws IOException if an error occurs writing the Entries file
0894:             */
0895:            public void removeEntry(File file) throws IOException {
0896:                adminHandler.removeEntry(file);
0897:            }
0898:
0899:            /**
0900:             * Remove the specified file from the local disk.
0901:             * If the file does not exist, the operation does nothing.
0902:
0903:             * @param pathname the full path to the file to remove
0904:             * @throws IOException if an IO error occurs while removing the file
0905:             */
0906:            public void removeLocalFile(String pathname) throws IOException {
0907:                transmitFileHandler.removeLocalFile(pathname);
0908:            }
0909:
0910:            /**
0911:             * Removes the specified file determined by pathName and repositoryName.
0912:             * In this implementation the filename from repositoryPath is added
0913:             * to the localpath (which doesn't have the filename in it) and that file is deleted.
0914:             */
0915:            public void removeLocalFile(String pathName, String repositoryName)
0916:                    throws IOException {
0917:                int ind = repositoryName.lastIndexOf('/');
0918:                if (ind <= 0) {
0919:                    return;
0920:                }
0921:
0922:                String fileName = repositoryName.substring(ind + 1);
0923:                String localFile = pathName + fileName;
0924:                File fileToDelete = new File(getLocalPath(), localFile);
0925:                removeLocalFile(fileToDelete.getAbsolutePath());
0926:                removeEntry(fileToDelete);
0927:            }
0928:
0929:            public void copyLocalFile(String pathname, String newName)
0930:                    throws IOException {
0931:                transmitFileHandler.copyLocalFile(pathname, newName);
0932:            }
0933:
0934:            /**
0935:             * Get the CVS event manager. This is generally called by response handlers
0936:             * that want to fire events.
0937:             * @return the eventManager
0938:             */
0939:            public EventManager getEventManager() {
0940:                return eventManager;
0941:            }
0942:
0943:            /**
0944:             * Get the global options that are set to this client.
0945:             * Individual commands can get the global options via this method.
0946:             */
0947:            public GlobalOptions getGlobalOptions() {
0948:                return globalOptions;
0949:            }
0950:
0951:            /**
0952:             * Call this method to abort the current command. The command will be
0953:             * aborted at the next suitable time
0954:             */
0955:            public synchronized void abort() {
0956:                abort = true;
0957:            }
0958:
0959:            /**
0960:             * Get all the files contained within a given
0961:             * directory that are <b>known to CVS</b>.
0962:             * @param directory the directory to look in
0963:             * @return a set of all files.
0964:             */
0965:            public Set getAllFiles(File directory) throws IOException {
0966:                return adminHandler.getAllFiles(directory);
0967:            }
0968:
0969:            public void setIgnoreFileFilter(IgnoreFileFilter ignoreFileFilter) {
0970:                this .ignoreFileFilter = ignoreFileFilter;
0971:            }
0972:
0973:            public IgnoreFileFilter getIgnoreFileFilter() {
0974:                return ignoreFileFilter;
0975:            }
0976:
0977:            public boolean shouldBeIgnored(File directory, String noneCvsFile) {
0978:                if (ignoreFileFilter != null) {
0979:                    return ignoreFileFilter.shouldBeIgnored(directory,
0980:                            noneCvsFile);
0981:                }
0982:                return false;
0983:            }
0984:
0985:            /**
0986:             * Checks for presence of CVS/Tag file and returns it's value.
0987:             * @return the value of CVS/Tag file for the specified directory
0988:             *          null if file doesn't exist
0989:             */
0990:            public String getStickyTagForDirectory(File directory) {
0991:                return adminHandler.getStickyTagForDirectory(directory);
0992:            }
0993:
0994:            /**
0995:             *  This method is called when a response for the ValidRequests request
0996:             * is received. 
0997:             * @param requests A List of requests that is valid for this CVS server 
0998:             * separated by spaces.
0999:             */
1000:            public void setValidRequests(String requests) {
1001:                // We need to tokenize the requests and add it to our map
1002:
1003:                StringTokenizer tokenizer = new StringTokenizer(requests);
1004:                String token;
1005:                while (tokenizer.hasMoreTokens()) {
1006:                    token = tokenizer.nextToken();
1007:                    // we just add an object with the corresponding request
1008:                    // as the key. 
1009:                    validRequests.put(token, this );
1010:                }
1011:
1012:            }
1013:
1014:            private int fillInitialRequests(List requests) {
1015:                int pos = 0;
1016:                requests.add(pos++, new RootRequest(getRepository()));
1017:                requests.add(pos++, new UseUnchangedRequest());
1018:                requests.add(pos++, new ValidRequestsRequest());
1019:                requests.add(pos++, new ValidResponsesRequest());
1020:                return pos;
1021:            }
1022:
1023:            /** This method is called by WrapperSendResponse for each wrapper setting sent
1024:             * back by the CVS server
1025:             * @param pattern A StringPattern indicating the pattern for which the
1026:             * wrapper applies
1027:             * @param option A KeywordSubstituionOption corresponding to the setting
1028:             */
1029:            public void addWrapper(StringPattern pattern,
1030:                    KeywordSubstitutionOptions option) {
1031:                if (wrappersMap == null) {
1032:                    throw new IllegalArgumentException(
1033:                            "This method should be called "
1034:                                    + "by WrapperSendResponse only.");
1035:                }
1036:                wrappersMap.put(pattern, option);
1037:            }
1038:
1039:            /** Returns the wrappers map associated with the CVS server
1040:             * The map is valid only after the connection is established
1041:             */
1042:            public Map getWrappersMap() throws CommandException {
1043:                if (wrappersMap == null) {
1044:                    wrappersMap = new HashMap();
1045:                    ArrayList requests = new ArrayList();
1046:                    requests.add(new WrapperSendRequest());
1047:                    boolean isFirst = isFirstCommand();
1048:                    try {
1049:                        processRequests(requests);
1050:                    } catch (Exception ex) {
1051:                        throw new CommandException(ex,
1052:                                "An error during obtaining server wrappers.");
1053:                    } finally {
1054:                        // Do not alter isFirstCommand property
1055:                        setIsFirstCommand(isFirst);
1056:                    }
1057:                    wrappersMap = Collections.unmodifiableMap(wrappersMap);
1058:                }
1059:                return wrappersMap;
1060:            }
1061:
1062:            /**
1063:             * Factory for creating clients.
1064:             */
1065:            public static interface Factory {
1066:
1067:                /**
1068:                 * Creates new client instance. Never null.
1069:                 * It uses fresh connection.
1070:                 */
1071:                Client createClient();
1072:            }
1073:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.