Source Code Cross Referenced for BasicCommand.java in  » IDE-Netbeans » cvsclient » org » netbeans » lib » cvsclient » command » 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.command 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*****************************************************************************
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is the CVS Client Library.
027:         * The Initial Developer of the Original Software is Robert Greig.
028:         * Portions created by Robert Greig are Copyright (C) 2000.
029:         * All Rights Reserved.
030:         *
031:         * If you wish your version of this file to be governed by only the CDDL
032:         * or only the GPL Version 2, indicate your decision by adding
033:         * "[Contributor] elects to include this software in this distribution
034:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
035:         * single choice of license, a recipient has the option to distribute
036:         * your version of this file under either the CDDL, the GPL Version 2 or
037:         * to extend the choice of license to its licensees as provided above.
038:         * However, if you add GPL Version 2 code and therefore, elected the GPL
039:         * Version 2 license, then the option applies only if the new code is
040:         * made subject to such option by the copyright holder.
041:         *
042:         * Contributor(s): Robert Greig.
043:         *****************************************************************************/package org.netbeans.lib.cvsclient.command;
044:
045:        import java.io.*;
046:        import java.util.*;
047:
048:        import org.netbeans.lib.cvsclient.*;
049:        import org.netbeans.lib.cvsclient.admin.*;
050:        import org.netbeans.lib.cvsclient.connection.*;
051:        import org.netbeans.lib.cvsclient.event.*;
052:        import org.netbeans.lib.cvsclient.request.*;
053:
054:        /**
055:         * A class that provides common functionality for many of the CVS command
056:         * that send similar sequences of requests.
057:         * @author  Robert Greig
058:         */
059:        public abstract class BasicCommand extends BuildableCommand {
060:            /**
061:             * The requests that are sent and processed.
062:             */
063:            protected List requests = new LinkedList();
064:
065:            /**
066:             * The client services that are provided to this command.
067:             */
068:            protected ClientServices clientServices;
069:
070:            /**
071:             * Whether to update recursively.
072:             */
073:            private boolean recursive = true;
074:
075:            /**
076:             * The files and/or directories to operate on.
077:             */
078:            protected File[] files;
079:
080:            /**
081:             * Gets the value of the recursive option.
082:             * @return true if recursive, false if not
083:             * @deprecated use isRecursive instead
084:             */
085:            public boolean getRecursive() {
086:                return recursive;
087:            }
088:
089:            /**
090:             * Gets the value of the recursive option.
091:             * @return true if recursive, false if not
092:             */
093:            public boolean isRecursive() {
094:                return recursive;
095:            }
096:
097:            /**
098:             * Sets the value of the recursive option.
099:             * @param recursive true if the command should recurse, false otherwise
100:             */
101:            public void setRecursive(boolean recursive) {
102:                this .recursive = recursive;
103:            }
104:
105:            /**
106:             * Set the files and/or directories on which to execute the command.
107:             * The way these are processed is:<P>
108:             * <UL><LI>Default action (i.e. not setting the files explicitly or
109:             * setting them to <pre>null</pre>) is to use the directory in which
110:             * the command was executed (see how directories are treated, below)</LI>
111:             * <LI>Files are handled how you would expect</LI>
112:             * <LI>For directories, all files within the directory are sent</LI></UL>
113:             * @param theFiles the files to operate on. May be null to indicate that the
114:             * local directory specified in the client should be used. Full, absolute
115:             * canonical pathnames <b>must</b> be supplied.
116:             */
117:            public void setFiles(File[] theFiles) {
118:                // sort array.. files first, directories follow
119:                if (theFiles == null) {
120:                    files = theFiles;
121:                    return;
122:                }
123:
124:                //        assert theFiles.length > 0 : "Empty array causes random AIOOBEs!";  // ClientRuntime.java:119
125:
126:                files = new File[theFiles.length];
127:                int fileCount = 0;
128:                int dirCount = 0;
129:                int totalCount = theFiles.length;
130:                for (int index = 0; index < totalCount; index++) {
131:                    File currentFile = theFiles[index];
132:                    if (currentFile.isDirectory()) {
133:                        files[totalCount - (1 + dirCount)] = currentFile;
134:                        dirCount = dirCount + 1;
135:                    } else {
136:                        files[fileCount] = currentFile;
137:                        fileCount = fileCount + 1;
138:                    }
139:                }
140:            }
141:
142:            /**
143:             * Get the files and/or directories specified for this command to operate
144:             * on.
145:             * @return the array of Files
146:             */
147:            public File[] getFiles() {
148:                return files;
149:            }
150:
151:            /**
152:             * Get a single file from the "files" list. returns only files, not directories.
153:             * This method is used from within the builders, because for single file requests, the
154:             * cvs server doesn't return us enough information to identify what file has been returned.
155:             * Thus we sort the "files" array (files come before directories. Then the response froms erver comes in the same order
156:             * and the files can be found this way.
157:             *
158:             * @param index the index of the file in the list.
159:             */
160:            public File getXthFile(int index) {
161:                if (index < 0 || index >= files.length) {
162:                    return null;
163:                }
164:                File file = files[index];
165:                if (!file.isFile()) {
166:                    return null;
167:                }
168:                return file;
169:            }
170:
171:            /**
172:             * @param ending - the ending part of the file's pathname.. path separator is cvs's default '/'
173:             */
174:            public File getFileEndingWith(String ending) {
175:                String locEnding = ending.replace('\\', '/');
176:                String localDir = getLocalDirectory().replace('\\', '/');
177:                int index = 0;
178:                for (index = 0; index < files.length; index++) {
179:                    String path = files[index].getAbsolutePath();
180:                    String parentPath = files[index].getParentFile()
181:                            .getAbsolutePath().replace('\\', '/');
182:                    path = path.replace('\\', '/');
183:                    if ((path.endsWith(locEnding) && locEnding.indexOf('/') >= 0)
184:                            || (files[index].getName().equals(locEnding) && parentPath
185:                                    .equals(localDir))) {
186:                        return files[index];
187:                    }
188:                }
189:                return null;
190:            }
191:
192:            /**
193:             * Add the appropriate requests for a specified path. For a directory,
194:             * process all the files within that directory and for a single file,
195:             * just send it. For each directory, send a directory request. For each
196:             * file send an Entry request followed by a Modified request.
197:             * @param path the particular path to issue requests for. May be
198:             * either a file or a directory.
199:             */
200:            private void addRequests(File path) throws FileNotFoundException,
201:                    IOException, CommandAbortedException {
202:                if (path == null) {
203:                    throw new IllegalArgumentException(
204:                            "Cannot add requests for a " + "null path.");
205:                }
206:
207:                if (!path.exists() || path.isFile()) {
208:                    addRequestsForFile(path);
209:                } else {
210:                    addRequestsForDirectory(path);
211:                }
212:            }
213:
214:            /**
215:             * Should return true if unchanged files should not be sent to server.
216:             * If false is returned, all files will be sent to server
217:             * This method is used by <code>sendEntryAndModifiedRequests</code>.
218:             */
219:            protected boolean doesCheckFileTime() {
220:                return true;
221:            }
222:
223:            /**
224:             * Send an Entry followed by a Modified or Unchanged request based on
225:             * whether the file has been untouched on the local machine.
226:             *
227:             * @param entry         the entry for the file
228:             * @param file          the file in question
229:             */
230:            protected void sendEntryAndModifiedRequests(Entry entry, File file) {
231:                if (entry == null) {
232:                    return;
233:                }
234:
235:                // for deleted added files, don't send anything..
236:                if (file != null && !file.exists() && entry.isNewUserFile()) {
237:                    return;
238:                }
239:
240:                Date entryLastModified = entry.getLastModified();
241:                boolean hadConflicts = entry.hadConflicts();
242:                if (!hadConflicts) {
243:                    // we null out the conflict field if there is no conflict
244:                    // because we use that field to store the timestamp of the
245:                    // file (just like command-line CVS). There is no point
246:                    // in sending this information to the CVS server, even
247:                    // though it should be ignored by the server.
248:                    entry.setConflict(null);
249:                } else if (fileRequiresConflictResolution(file, entry)) {
250:                    // send entry in wire conflict format
251:                    Entry clone = new Entry(entry.toString());
252:                    clone
253:                            .setConflict(Entry.HAD_CONFLICTS_AND_TIMESTAMP_MATCHES_FILE);
254:                    entry = clone;
255:                }
256:                addRequest(new EntryRequest(entry));
257:
258:                if (file == null || !file.exists()
259:                        || entry.isUserFileToBeRemoved()) {
260:                    return;
261:                }
262:
263:                if (doesCheckFileTime() && !hadConflicts
264:                        && entryLastModified != null) {
265:                    if (DateComparator.getInstance().equals(
266:                            file.lastModified(), entryLastModified.getTime())) {
267:                        addRequest(new UnchangedRequest(file.getName()));
268:                        return;
269:                    }
270:                }
271:
272:                addRequest(new ModifiedRequest(file, entry.isBinary()));
273:            }
274:
275:            /**
276:             * When committing, we need to perform a check that will prevent the
277:             * unmodified conflicting files from being checked in. This is the behavior
278:             * of command line CVS client. This method checks the Entry for the file
279:             * against the time stamp. The user can optimally call this method only if
280:             * the Entry for the file indicates a conflict
281:             * @param entry The Entry object corresponding to the file
282:             * @param file The File object representing the file on the filesystem
283:             * @return boolean Returns true if the file's timestamp is same or less than
284:             * the time when the conflicting merge was done by CVS update as indicated
285:             * by the Entry.
286:             */
287:            private final boolean fileRequiresConflictResolution(File file,
288:                    Entry entry) {
289:
290:                if (file == null)
291:                    return false; // null file is set by clean copy
292:
293:                boolean ret = false;
294:
295:                if (entry.hadConflicts()) {
296:                    // TODO introduce common timestamp comparation logic
297:                    // We only test accuracy of upto a second (1000ms) because that is
298:                    // the precision of the timestamp in the entries file
299:                    long mergedTime = entry.getLastModified().getTime() / 1000;
300:                    long timeStampOfFile = file.lastModified() / 1000;
301:                    ret = timeStampOfFile <= mergedTime;
302:                }
303:
304:                return ret;
305:            }
306:
307:            /**
308:             * Adds the appropriate requests for a given directory. Sends a
309:             * directory request followed by as many Entry and Modified requests
310:             * as required
311:             * @param directory the directory to send requests for
312:             * @throws IOException if an error occurs constructing the requests
313:             */
314:            protected void addRequestsForDirectory(File directory)
315:                    throws IOException, CommandAbortedException {
316:                if (!clientServices.exists(directory)) {
317:                    return;
318:                }
319:                if (clientServices.isAborted()) {
320:                    throw new CommandAbortedException(
321:                            "Command aborted during request generation",
322:                            "Command aborted during request generation");
323:                }
324:
325:                addDirectoryRequest(directory);
326:
327:                File[] dirFiles = directory.listFiles();
328:                List localFiles;
329:                if (dirFiles == null) {
330:                    localFiles = new ArrayList(0);
331:                } else {
332:                    localFiles = new ArrayList(Arrays.asList(dirFiles));
333:                    localFiles.remove(new File(directory, "CVS"));
334:                }
335:
336:                List subDirectories = null;
337:                if (isRecursive()) {
338:                    subDirectories = new LinkedList();
339:                }
340:
341:                // get all the entries we know about, and process them
342:                for (Iterator it = clientServices.getEntries(directory); it
343:                        .hasNext();) {
344:                    final Entry entry = (Entry) it.next();
345:                    final File file = new File(directory, entry.getName());
346:                    if (entry.isDirectory()) {
347:                        if (isRecursive()) {
348:                            subDirectories.add(new File(directory, entry
349:                                    .getName()));
350:                        }
351:                    } else {
352:                        addRequestForFile(file, entry);
353:                    }
354:                    localFiles.remove(file);
355:                }
356:
357:                // In case that CVS folder does not exist, we need to process all
358:                // directories that have CVS subfolders:
359:                if (isRecursive() && !new File(directory, "CVS").exists()) {
360:                    File[] subFiles = directory.listFiles();
361:                    if (subFiles != null) {
362:                        for (int i = 0; i < subFiles.length; i++) {
363:                            if (subFiles[i].isDirectory()
364:                                    && new File(subFiles[i], "CVS").exists()) {
365:                                subDirectories.add(subFiles[i]);
366:                            }
367:                        }
368:                    }
369:                }
370:
371:                for (Iterator it = localFiles.iterator(); it.hasNext();) {
372:                    String localFileName = ((File) it.next()).getName();
373:                    if (!clientServices.shouldBeIgnored(directory,
374:                            localFileName)) {
375:                        addRequest(new QuestionableRequest(localFileName));
376:                    }
377:                }
378:
379:                if (isRecursive()) {
380:                    for (Iterator it = subDirectories.iterator(); it.hasNext();) {
381:                        File subdirectory = (File) it.next();
382:                        File cvsSubDir = new File(subdirectory, "CVS"); //NOI18N
383:                        if (clientServices.exists(cvsSubDir)) {
384:                            addRequestsForDirectory(subdirectory);
385:                        }
386:                    }
387:                }
388:            }
389:
390:            /**
391:             * This method is called for each explicit file and for files within a
392:             * directory.
393:             */
394:            protected void addRequestForFile(File file, Entry entry) {
395:                sendEntryAndModifiedRequests(entry, file);
396:            }
397:
398:            /**
399:             * Add the appropriate requests for a single file. A directory request
400:             * is sent, followed by an Entry and Modified request
401:             * @param file the file to send requests for
402:             * @throws IOException if an error occurs constructing the requests
403:             */
404:            protected void addRequestsForFile(File file) throws IOException {
405:                addDirectoryRequest(file.getParentFile());
406:
407:                try {
408:                    final Entry entry = clientServices.getEntry(file);
409:                    // a non-null entry means the file does exist in the
410:                    // Entries file for this directory
411:                    if (entry != null) {
412:                        addRequestForFile(file, entry);
413:                    } else if (file.exists()) {
414:                        // #50963 file exists locally without an entry AND the request is
415:                        // for the file explicitly
416:                        boolean unusedBinaryFlag = false;
417:                        addRequest(new ModifiedRequest(file, unusedBinaryFlag));
418:                    }
419:                } catch (IOException ex) {
420:                    System.err.println("An error occurred getting the Entry "
421:                            + "for file " + file + ": " + ex);
422:                    ex.printStackTrace();
423:                }
424:            }
425:
426:            /**
427:             * Adds a DirectoryRequest (and maybe a StickyRequest) to the request list.
428:             */
429:            protected final void addDirectoryRequest(File directory) {
430:                // remove localPath prefix from directory. If left with
431:                // nothing, use dot (".") in the directory request
432:                String dir = getRelativeToLocalPathInUnixStyle(directory);
433:
434:                try {
435:                    String repository = clientServices
436:                            .getRepositoryForDirectory(directory
437:                                    .getAbsolutePath());
438:                    addRequest(new DirectoryRequest(dir, repository));
439:                    String tag = clientServices
440:                            .getStickyTagForDirectory(directory);
441:                    if (tag != null) {
442:                        addRequest(new StickyRequest(tag));
443:                    }
444:                } catch (FileNotFoundException ex) {
445:                    // we can ignore this exception safely because it just means
446:                    // that the user has deleted a directory referenced in a
447:                    // CVS/Entries file
448:                } catch (IOException ex) {
449:                    System.err
450:                            .println("An error occurred reading the respository "
451:                                    + "for the directory " + dir + ": " + ex);
452:                    ex.printStackTrace();
453:                }
454:            }
455:
456:            /**
457:             * Add the argument requests. The argument requests are created using
458:             * the original set of files/directories passed in. Subclasses of this
459:             * class should call this method at the appropriate point in their
460:             * execute() method. Note that arguments are appended to the list.
461:             */
462:            protected void addArgumentRequests() {
463:                if (files == null) {
464:                    return;
465:                }
466:
467:                for (int i = 0; i < files.length; i++) {
468:                    final File file = files[i];
469:                    String relativePath = getRelativeToLocalPathInUnixStyle(file);
470:                    addRequest(new ArgumentRequest(relativePath, true));
471:                }
472:            }
473:
474:            /**
475:             * Execute a command. This implementation sends a Root request, followed
476:             * by as many Directory and Entry requests as is required by the recurse
477:             * setting and the file arguments that have been set. Subclasses should
478:             * call this first, and tag on the end of the requests list any further
479:             * requests and, finally, the actually request that does the command (e.g.
480:             * <pre>update</pre>, <pre>status</pre> etc.)
481:             * @param client the client services object that provides any necessary
482:             * services to this command, including the ability to actually process
483:             * all the requests
484:             * @throws CommandException if an error occurs executing the command
485:             */
486:            public void execute(ClientServices client, EventManager em)
487:                    throws CommandException, AuthenticationException {
488:                requests.clear();
489:                clientServices = client;
490:                super .execute(client, em);
491:
492:                if (client.isFirstCommand()) {
493:                    addRequest(new RootRequest(client.getRepository()));
494:                }
495:
496:                addFileRequests();
497:            }
498:
499:            private void addFileRequests() throws CommandException {
500:                try {
501:                    if (files != null && files.length > 0) {
502:                        for (int i = 0; i < files.length; i++) {
503:                            addRequests(files[i]);
504:                        }
505:                    } else {
506:                        // if no arguments have been specified, then specify the
507:                        // local directory - the "top level" for this command
508:                        if (assumeLocalPathWhenUnspecified()) {
509:                            addRequests(new File(getLocalDirectory()));
510:                        }
511:                    }
512:                } catch (Exception ex) {
513:                    throw new CommandException(ex, ex.getLocalizedMessage());
514:                }
515:            }
516:
517:            /**
518:             * The result from this command is used only when the getFiles() returns null or empty array.
519:             * in such a case and when this method returns true, it is assumed the localpath should be taken
520:             * as the 'default' file for the building of requests.
521:             * Generally assumed to be true. Can be overriden by subclasses. However make sure you know what you are doing. :)
522:             */
523:            protected boolean assumeLocalPathWhenUnspecified() {
524:                return true;
525:            }
526:
527:            /**
528:             * Adds the specified request to the request list.
529:             */
530:            protected final void addRequest(Request request) {
531:                requests.add(request);
532:            }
533:
534:            /**
535:             * Adds the request for the current working directory.
536:             */
537:            protected final void addRequestForWorkingDirectory(
538:                    ClientServices clientServices) throws IOException {
539:                addRequest(new DirectoryRequest(".", //NOI18N
540:                        clientServices
541:                                .getRepositoryForDirectory(getLocalDirectory())));
542:            }
543:
544:            /**
545:             * If the specified value is true, add a ArgumentRequest for the specified
546:             * argument.
547:             */
548:            protected final void addArgumentRequest(boolean value,
549:                    String argument) {
550:                if (!value) {
551:                    return;
552:                }
553:
554:                addRequest(new ArgumentRequest(argument));
555:            }
556:
557:            /**
558:             * Appends the file's names to the specified buffer.
559:             */
560:            protected final void appendFileArguments(StringBuffer buffer) {
561:                File[] files = getFiles();
562:                if (files == null) {
563:                    return;
564:                }
565:
566:                for (int index = 0; index < files.length; index++) {
567:                    if (index > 0) {
568:                        buffer.append(' ');
569:                    }
570:                    buffer.append(files[index].getName());
571:                }
572:            }
573:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.