Source Code Cross Referenced for CommitAction.java in  » IDE-Netbeans » subversion » org » netbeans » modules » subversion » ui » commit » 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 » subversion » org.netbeans.modules.subversion.ui.commit 
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 NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.modules.subversion.ui.commit;
043:
044:        import org.netbeans.modules.versioning.util.DialogBoundsPreserver;
045:        import org.netbeans.modules.subversion.client.SvnClient;
046:        import org.netbeans.modules.subversion.ui.actions.ContextAction;
047:        import org.netbeans.modules.subversion.util.Context;
048:        import org.netbeans.modules.subversion.*;
049:        import org.openide.DialogDescriptor;
050:        import org.openide.DialogDisplayer;
051:        import org.openide.nodes.Node;
052:        import org.tigris.subversion.svnclientadapter.SVNBaseDir;
053:        import org.tigris.subversion.svnclientadapter.SVNClientException;
054:        import javax.swing.*;
055:        import java.awt.*;
056:        import java.io.File;
057:        import java.util.*;
058:        import java.util.List;
059:        import java.text.MessageFormat;
060:        import javax.swing.event.TableModelEvent;
061:        import javax.swing.event.TableModelListener;
062:        import org.netbeans.modules.subversion.client.SvnClientExceptionHandler;
063:        import org.netbeans.modules.subversion.client.SvnProgressSupport;
064:        import org.netbeans.modules.subversion.util.SvnUtils;
065:        import org.netbeans.modules.versioning.util.VersioningListener;
066:        import org.netbeans.modules.versioning.util.VersioningEvent;
067:        import org.netbeans.modules.versioning.util.Utils;
068:        import org.openide.util.HelpCtx;
069:        import org.openide.util.RequestProcessor;
070:        import org.openide.util.NbBundle;
071:        import org.tigris.subversion.svnclientadapter.ISVNProperty;
072:        import org.tigris.subversion.svnclientadapter.SVNRevision;
073:        import org.tigris.subversion.svnclientadapter.SVNUrl;
074:
075:        /**
076:         * Commit action
077:         *
078:         * @author Petr Kuzel
079:         */
080:        public class CommitAction extends ContextAction {
081:
082:            static final String RECENT_COMMIT_MESSAGES = "recentCommitMessage";
083:
084:            protected String getBaseName(Node[] nodes) {
085:                return "CTL_MenuItem_Commit"; // NOI18N
086:            }
087:
088:            protected boolean enable(Node[] nodes) {
089:                if (isDeepRefresh()) {
090:                    // allway true as we have will accept and check for external changes 
091:                    // and we don't about them yet 
092:                    return true;
093:                }
094:                // XXX could be a performace issue, maybe a msg box in commit would be enough
095:                FileStatusCache cache = Subversion.getInstance()
096:                        .getStatusCache();
097:                File[] files = cache.listFiles(getContext(nodes),
098:                        FileInformation.STATUS_LOCAL_CHANGE);
099:                return files.length > 0;
100:            }
101:
102:            /** Run commit action. Shows UI */
103:            public static void commit(String contentTitle, final Context ctx) {
104:                if (!Subversion.getInstance().checkClientAvailable()) {
105:                    return;
106:                }
107:
108:                if (isDeepRefresh()) {
109:                    commitAllChanges(contentTitle, ctx);
110:                } else {
111:                    commitKnownChanges(contentTitle, ctx);
112:                }
113:            }
114:
115:            private static boolean isDeepRefresh() {
116:                String noDeepRefresh = System
117:                        .getProperty("netbeans.subversion.commit.deepStatusRefresh"); // NOI18N
118:                return noDeepRefresh != null
119:                        && !noDeepRefresh.trim().equals("");
120:            }
121:
122:            /**
123:             * Opens the commit dialog displaying all changed files from the status cache which belong to the given context.
124:             * There is no guarantee that changes made outside of the IDE will be recognized
125:             * 
126:             * @param contentTitle
127:             * @param ctx
128:             */
129:            public static void commitKnownChanges(String contentTitle,
130:                    final Context ctx) {
131:
132:                // get files list
133:                List<File> fileList = getFiles(ctx);
134:                if (fileList.size() == 0) {
135:                    return;
136:                }
137:
138:                // show commit dialog                
139:                final CommitPanel panel = new CommitPanel();
140:                final CommitTable data = new CommitTable(panel.filesLabel,
141:                        CommitTable.COMMIT_COLUMNS,
142:                        new String[] { CommitTableModel.COLUMN_NAME_PATH });
143:                panel.setCommitTable(data);
144:
145:                data.setNodes(getFileNodes(fileList));
146:
147:                final JButton commitButton = new JButton();
148:                if (showCommitDialog(panel, data, commitButton, contentTitle,
149:                        ctx) == commitButton) {
150:                    // if OK setup sequence of add, remove and commit calls
151:                    startCommitTask(panel, data, ctx);
152:                }
153:
154:            }
155:
156:            /**
157:             * Opens the commit dialog displaying all changed files from the status cache which belong to the given context.
158:             * The status for all files will be refrehed first and the commit button in the dialog stays disabled until then.
159:             * It may take a while until the dialog is setup.
160:             * 
161:             * @param contentTitle
162:             * @param ctx
163:             */
164:            public static void commitAllChanges(String contentTitle,
165:                    final Context ctx) {
166:
167:                final CommitPanel panel = new CommitPanel();
168:                final CommitTable data = new CommitTable(panel.filesLabel,
169:                        CommitTable.COMMIT_COLUMNS,
170:                        new String[] { CommitTableModel.COLUMN_NAME_PATH });
171:                panel.setCommitTable(data);
172:                final JButton commitButton = new JButton();
173:
174:                // start backround prepare
175:                SVNUrl repository = null;
176:                try {
177:                    repository = getSvnUrl(ctx);
178:                } catch (SVNClientException ex) {
179:                    SvnClientExceptionHandler.notifyException(ex, true, true);
180:                }
181:                SvnProgressSupport prepareSupport = getPrepareSupport(ctx,
182:                        data, commitButton, panel);
183:                RequestProcessor rp = Subversion.getInstance()
184:                        .getRequestProcessor(repository);
185:                prepareSupport.start(rp, repository, org.openide.util.NbBundle
186:                        .getMessage(CommitAction.class, "BK1009")); // NOI18N
187:
188:                // show commit dialog        
189:                if (showCommitDialog(panel, data, commitButton, contentTitle,
190:                        ctx) == commitButton) {
191:                    // if OK setup sequence of add, remove and commit calls
192:                    startCommitTask(panel, data, ctx);
193:                } else {
194:                    prepareSupport.cancel();
195:                }
196:            }
197:
198:            /**
199:             * Returns all files from the given context honoring the flat folder logic
200:             * 
201:             * @param ctx
202:             * @return
203:             */
204:            private static List<File> getFiles(Context ctx) {
205:                List<File> fileList = new ArrayList<File>();
206:                // get files without exclusions
207:                File[] contextFiles = ctx.getFiles();
208:                if (contextFiles.length == 0) {
209:                    return fileList;
210:                }
211:
212:                FileStatusCache cache = Subversion.getInstance()
213:                        .getStatusCache();
214:
215:                // The commits are made non recursively, so 
216:                // add also the roots to the to be commited list.       
217:                List<File> rootFiles = ctx.getRoots();
218:                Set<File> filesSet = new HashSet<File>();
219:                for (File file : contextFiles) {
220:                    filesSet.add(file);
221:                }
222:                for (File file : rootFiles) {
223:                    filesSet.add(file);
224:                }
225:                contextFiles = filesSet.toArray(new File[filesSet.size()]);
226:
227:                // get all changed files while honoring the flat folder logic
228:                File[][] split = Utils.splitFlatOthers(contextFiles);
229:                for (int c = 0; c < split.length; c++) {
230:                    contextFiles = split[c];
231:                    boolean recursive = c == 1;
232:                    if (recursive) {
233:                        File[] files = cache.listFiles(ctx,
234:                                FileInformation.STATUS_LOCAL_CHANGE);
235:                        for (int i = 0; i < files.length; i++) {
236:                            for (int r = 0; r < contextFiles.length; r++) {
237:                                if (SvnUtils.isParentOrEqual(contextFiles[r],
238:                                        files[i])) {
239:                                    if (!fileList.contains(files[i])) {
240:                                        fileList.add(files[i]);
241:                                    }
242:                                }
243:                            }
244:                        }
245:                    } else {
246:                        File[] files = SvnUtils.flatten(contextFiles,
247:                                FileInformation.STATUS_LOCAL_CHANGE);
248:                        for (int i = 0; i < files.length; i++) {
249:                            if (!fileList.contains(files[i])) {
250:                                fileList.add(files[i]);
251:                            }
252:                        }
253:                    }
254:                }
255:                return fileList;
256:            }
257:
258:            /**
259:             * Returns a SvnFileNode for each given file
260:             * 
261:             * @param fileList
262:             * @return
263:             */
264:            private static SvnFileNode[] getFileNodes(List<File> fileList) {
265:                SvnFileNode[] nodes;
266:                ArrayList<SvnFileNode> nodesList = new ArrayList<SvnFileNode>(
267:                        fileList.size());
268:
269:                for (Iterator<File> it = fileList.iterator(); it.hasNext();) {
270:                    File file = it.next();
271:                    SvnFileNode node = new SvnFileNode(file);
272:                    nodesList.add(node);
273:                }
274:                nodes = nodesList.toArray(new SvnFileNode[fileList.size()]);
275:                return nodes;
276:            }
277:
278:            /**
279:             * Opens the commit dlg
280:             * 
281:             * @param panel
282:             * @param data
283:             * @param commitButton
284:             * @param contentTitle
285:             * @param ctx
286:             * @return
287:             */
288:            private static Object showCommitDialog(final CommitPanel panel,
289:                    final CommitTable data, final JButton commitButton,
290:                    String contentTitle, final Context ctx) {
291:                JComponent component = data.getComponent();
292:                panel.filesPanel.setLayout(new BorderLayout());
293:                panel.filesPanel.add(component, BorderLayout.CENTER);
294:
295:                DialogDescriptor dd = new DialogDescriptor(panel,
296:                        org.openide.util.NbBundle.getMessage(
297:                                CommitAction.class, "CTL_CommitDialog_Title",
298:                                contentTitle)); // NOI18N
299:                dd.setModal(true);
300:                org.openide.awt.Mnemonics
301:                        .setLocalizedText(commitButton,
302:                                org.openide.util.NbBundle.getMessage(
303:                                        CommitAction.class,
304:                                        "CTL_Commit_Action_Commit"));
305:                commitButton.getAccessibleContext().setAccessibleName(
306:                        org.openide.util.NbBundle
307:                                .getMessage(CommitAction.class,
308:                                        "ACSN_Commit_Action_Commit"));
309:                commitButton.getAccessibleContext().setAccessibleDescription(
310:                        org.openide.util.NbBundle
311:                                .getMessage(CommitAction.class,
312:                                        "ACSD_Commit_Action_Commit"));
313:                final JButton cancelButton = new JButton(
314:                        org.openide.util.NbBundle.getMessage(
315:                                CommitAction.class, "CTL_Commit_Action_Cancel")); // NOI18N
316:                org.openide.awt.Mnemonics
317:                        .setLocalizedText(cancelButton,
318:                                org.openide.util.NbBundle.getMessage(
319:                                        CommitAction.class,
320:                                        "CTL_Commit_Action_Cancel"));
321:                cancelButton.getAccessibleContext().setAccessibleName(
322:                        org.openide.util.NbBundle
323:                                .getMessage(CommitAction.class,
324:                                        "ACSN_Commit_Action_Cancel"));
325:                cancelButton.getAccessibleContext().setAccessibleDescription(
326:                        org.openide.util.NbBundle
327:                                .getMessage(CommitAction.class,
328:                                        "ACSD_Commit_Action_Cancel"));
329:
330:                commitButton.setEnabled(false);
331:                dd.setOptions(new Object[] { commitButton, cancelButton }); // NOI18N
332:                dd.setHelpCtx(new HelpCtx(CommitAction.class));
333:                panel.addVersioningListener(new VersioningListener() {
334:                    public void versioningEvent(VersioningEvent event) {
335:                        refreshCommitDialog(panel, data, commitButton);
336:                    }
337:                });
338:                data.getTableModel().addTableModelListener(
339:                        new TableModelListener() {
340:                            public void tableChanged(TableModelEvent e) {
341:                                refreshCommitDialog(panel, data, commitButton);
342:                            }
343:                        });
344:                commitButton.setEnabled(containsCommitable(data));
345:
346:                panel.putClientProperty("contentTitle", contentTitle); // NOI18N
347:                panel.putClientProperty("DialogDescriptor", dd); // NOI18N
348:                final Dialog dialog = DialogDisplayer.getDefault()
349:                        .createDialog(dd);
350:                dialog.addWindowListener(new DialogBoundsPreserver(
351:                        SvnModuleConfig.getDefault().getPreferences(),
352:                        "svn.commit.dialog")); // NOI18N       
353:                dialog.pack();
354:                dialog.setVisible(true);
355:
356:                return dd.getValue();
357:            }
358:
359:            private static void startCommitTask(final CommitPanel panel,
360:                    final CommitTable data, final Context ctx) {
361:                final Map<SvnFileNode, CommitOptions> commitFiles = data
362:                        .getCommitFiles();
363:                final String message = panel.messageTextArea.getText();
364:                org.netbeans.modules.versioning.util.Utils.insert(
365:                        SvnModuleConfig.getDefault().getPreferences(),
366:                        RECENT_COMMIT_MESSAGES, message, 20);
367:
368:                SVNUrl repository = null;
369:                try {
370:                    repository = getSvnUrl(ctx);
371:                } catch (SVNClientException ex) {
372:                    SvnClientExceptionHandler.notifyException(ex, true, true);
373:                }
374:                RequestProcessor rp = Subversion.getInstance()
375:                        .getRequestProcessor(repository);
376:                SvnProgressSupport support = new SvnProgressSupport() {
377:                    public void perform() {
378:                        performCommit(message, commitFiles, ctx, this );
379:                    }
380:                };
381:                support.start(rp, repository, org.openide.util.NbBundle
382:                        .getMessage(CommitAction.class, "LBL_Commit_Progress")); // NOI18N        
383:            }
384:
385:            private static SvnProgressSupport getPrepareSupport(
386:                    final Context ctx, final CommitTable data,
387:                    final JButton commitButton, final CommitPanel panel) {
388:                SvnProgressSupport support = new SvnProgressSupport() {
389:                    public void perform() {
390:                        try {
391:                            // get files without exclusions
392:                            File[] contextFiles = ctx.getFiles();
393:                            if (contextFiles.length == 0) {
394:                                return;
395:                            }
396:
397:                            // The commits are made non recursively, so 
398:                            // add also the roots to the to be commited list.       
399:                            List<File> rootFiles = ctx.getRoots();
400:                            Set<File> filesSet = new HashSet<File>();
401:                            for (File file : contextFiles) {
402:                                filesSet.add(file);
403:                            }
404:                            for (File file : rootFiles) {
405:                                filesSet.add(file);
406:                            }
407:                            contextFiles = filesSet.toArray(new File[filesSet
408:                                    .size()]);
409:
410:                            // make a deep refresh to get the not yet notified external changes
411:                            FileStatusCache cache = Subversion.getInstance()
412:                                    .getStatusCache();
413:                            for (File f : contextFiles) {
414:                                SvnUtils.refreshRecursively(f);
415:                            }
416:                            // get all changed files while honoring the flat folder logic
417:                            File[][] split = Utils
418:                                    .splitFlatOthers(contextFiles);
419:                            List<File> fileList = new ArrayList<File>();
420:                            for (int c = 0; c < split.length; c++) {
421:                                contextFiles = split[c];
422:                                boolean recursive = c == 1;
423:                                if (recursive) {
424:                                    File[] files = cache
425:                                            .listFiles(
426:                                                    ctx,
427:                                                    FileInformation.STATUS_LOCAL_CHANGE);
428:                                    for (int i = 0; i < files.length; i++) {
429:                                        for (int r = 0; r < contextFiles.length; r++) {
430:                                            if (SvnUtils.isParentOrEqual(
431:                                                    contextFiles[r], files[i])) {
432:                                                if (!fileList
433:                                                        .contains(files[i])) {
434:                                                    fileList.add(files[i]);
435:                                                }
436:                                            }
437:                                        }
438:                                    }
439:                                } else {
440:                                    File[] files = SvnUtils
441:                                            .flatten(
442:                                                    contextFiles,
443:                                                    FileInformation.STATUS_LOCAL_CHANGE);
444:                                    for (int i = 0; i < files.length; i++) {
445:                                        if (!fileList.contains(files[i])) {
446:                                            fileList.add(files[i]);
447:                                        }
448:                                    }
449:                                }
450:                            }
451:
452:                            if (fileList.size() == 0) {
453:                                return;
454:                            }
455:
456:                            ArrayList<SvnFileNode> nodesList = new ArrayList<SvnFileNode>(
457:                                    fileList.size());
458:                            SvnFileNode[] nodes;
459:                            for (Iterator<File> it = fileList.iterator(); it
460:                                    .hasNext();) {
461:                                File file = it.next();
462:                                SvnFileNode node = new SvnFileNode(file);
463:                                nodesList.add(node);
464:                            }
465:                            nodes = nodesList.toArray(new SvnFileNode[fileList
466:                                    .size()]);
467:                            data.setNodes(nodes);
468:                        } finally {
469:                            commitButton.setEnabled(containsCommitable(data));
470:
471:                            panel
472:                                    .addVersioningListener(new VersioningListener() {
473:                                        public void versioningEvent(
474:                                                VersioningEvent event) {
475:                                            refreshCommitDialog(panel, data,
476:                                                    commitButton);
477:                                        }
478:                                    });
479:                            data.getTableModel().addTableModelListener(
480:                                    new TableModelListener() {
481:                                        public void tableChanged(
482:                                                TableModelEvent e) {
483:                                            refreshCommitDialog(panel, data,
484:                                                    commitButton);
485:                                        }
486:                                    });
487:                        }
488:                    }
489:                };
490:                return support;
491:            }
492:
493:            private static boolean containsCommitable(CommitTable data) {
494:                Map<SvnFileNode, CommitOptions> map = data.getCommitFiles();
495:                for (CommitOptions co : map.values()) {
496:                    if (co != CommitOptions.EXCLUDE) {
497:                        return true;
498:                    }
499:                }
500:                return false;
501:            }
502:
503:            /**
504:             * User changed a commit action.
505:             * 
506:             * @param panel
507:             * @param commit
508:             */
509:            private static void refreshCommitDialog(CommitPanel panel,
510:                    CommitTable table, JButton commit) {
511:                ResourceBundle loc = NbBundle.getBundle(CommitAction.class);
512:                Map<SvnFileNode, CommitOptions> files = table.getCommitFiles();
513:                Set<String> stickyTags = new HashSet<String>();
514:                boolean conflicts = false;
515:
516:                boolean enabled = commit.isEnabled();
517:
518:                for (SvnFileNode fileNode : files.keySet()) {
519:                    CommitOptions options = files.get(fileNode);
520:                    if (options == CommitOptions.EXCLUDE)
521:                        continue;
522:                    stickyTags.add(SvnUtils.getCopy(fileNode.getFile()));
523:                    int status = fileNode.getInformation().getStatus();
524:                    if ((status & FileInformation.STATUS_REMOTE_CHANGE) != 0
525:                            || status == FileInformation.STATUS_VERSIONED_CONFLICT) {
526:                        enabled = false;
527:                        String msg = (status == FileInformation.STATUS_VERSIONED_CONFLICT) ? loc
528:                                .getString("MSG_CommitForm_ErrorConflicts")
529:                                : loc
530:                                        .getString("MSG_CommitForm_ErrorRemoteChanges");
531:                        panel.setErrorLabel("<html><font color=\"#002080\">"
532:                                + msg + "</font></html>"); // NOI18N
533:                        conflicts = true;
534:                    }
535:                }
536:
537:                if (stickyTags.size() > 1) {
538:                    table.setColumns(new String[] {
539:                            CommitTableModel.COLUMN_NAME_NAME,
540:                            CommitTableModel.COLUMN_NAME_BRANCH,
541:                            CommitTableModel.COLUMN_NAME_STATUS,
542:                            CommitTableModel.COLUMN_NAME_ACTION,
543:                            CommitTableModel.COLUMN_NAME_PATH });
544:                } else {
545:                    table.setColumns(new String[] {
546:                            CommitTableModel.COLUMN_NAME_NAME,
547:                            CommitTableModel.COLUMN_NAME_STATUS,
548:                            CommitTableModel.COLUMN_NAME_ACTION,
549:                            CommitTableModel.COLUMN_NAME_PATH });
550:                }
551:
552:                String contentTitle = (String) panel
553:                        .getClientProperty("contentTitle"); // NOI18N
554:                DialogDescriptor dd = (DialogDescriptor) panel
555:                        .getClientProperty("DialogDescriptor"); // NOI18N
556:                String errorLabel;
557:                if (stickyTags.size() <= 1) {
558:                    String stickyTag = stickyTags.size() == 0 ? null
559:                            : (String) stickyTags.iterator().next();
560:                    if (stickyTag == null) {
561:                        dd.setTitle(MessageFormat.format(loc
562:                                .getString("CTL_CommitDialog_Title"),
563:                                new Object[] { contentTitle }));
564:                        errorLabel = ""; // NOI18N
565:                    } else {
566:                        dd.setTitle(MessageFormat.format(loc
567:                                .getString("CTL_CommitDialog_Title_Branch"),
568:                                new Object[] { contentTitle, stickyTag }));
569:                        String msg = MessageFormat.format(loc
570:                                .getString("MSG_CommitForm_InfoBranch"),
571:                                new Object[] { stickyTag });
572:                        errorLabel = "<html><font color=\"#002080\">" + msg
573:                                + "</font></html>"; // NOI18N
574:                    }
575:                } else {
576:                    dd.setTitle(MessageFormat.format(loc
577:                            .getString("CTL_CommitDialog_Title_Branches"),
578:                            new Object[] { contentTitle }));
579:                    String msg = loc
580:                            .getString("MSG_CommitForm_ErrorMultipleBranches");
581:                    errorLabel = "<html><font color=\"#CC0000\">" + msg
582:                            + "</font></html>"; // NOI18N
583:                }
584:                if (!conflicts) {
585:                    panel.setErrorLabel(errorLabel);
586:                    enabled = true;
587:                }
588:                commit.setEnabled(enabled && containsCommitable(table));
589:            }
590:
591:            protected void performContextAction(Node[] nodes) {
592:                if (!Subversion.getInstance().checkClientAvailable()) {
593:                    return;
594:                }
595:                final Context ctx = getContext(nodes);
596:                commit(getContextDisplayName(nodes), ctx);
597:            }
598:
599:            public static void performCommit(String message,
600:                    Map<SvnFileNode, CommitOptions> commitFiles, Context ctx,
601:                    SvnProgressSupport support) {
602:                performCommit(message, commitFiles, ctx, support, false);
603:            }
604:
605:            public static void performCommit(String message,
606:                    Map<SvnFileNode, CommitOptions> commitFiles, Context ctx,
607:                    SvnProgressSupport support, boolean rootUpdate) {
608:                try {
609:
610:                    SvnClient client;
611:                    try {
612:                        client = Subversion.getInstance().getClient(ctx,
613:                                support);
614:                    } catch (SVNClientException ex) {
615:                        SvnClientExceptionHandler.notifyException(ex, true,
616:                                true); // should not hapen
617:                        return;
618:                    }
619:                    support.setDisplayName(org.openide.util.NbBundle
620:                            .getMessage(CommitAction.class,
621:                                    "LBL_Commit_Progress")); // NOI18N
622:
623:                    List<SvnFileNode> addCandidates = new ArrayList<SvnFileNode>();
624:                    List<File> removeCandidates = new ArrayList<File>();
625:                    Set<File> commitCandidates = new LinkedHashSet<File>();
626:                    Set<File> binnaryCandidates = new HashSet<File>();
627:
628:                    Iterator<SvnFileNode> it = commitFiles.keySet().iterator();
629:                    // XXX refactor the olowing loop. there seem to be redundant blocks
630:                    while (it.hasNext()) {
631:                        if (support.isCanceled()) {
632:                            return;
633:                        }
634:                        SvnFileNode node = it.next();
635:                        CommitOptions option = commitFiles.get(node);
636:                        if (CommitOptions.ADD_BINARY == option) {
637:                            List<File> l = listUnmanagedParents(node);
638:                            Iterator<File> dit = l.iterator();
639:                            while (dit.hasNext()) {
640:                                if (support.isCanceled()) {
641:                                    return;
642:                                }
643:                                File file = dit.next();
644:                                addCandidates.add(new SvnFileNode(file));
645:                                commitCandidates.add(file);
646:                            }
647:
648:                            if (support.isCanceled()) {
649:                                return;
650:                            }
651:                            binnaryCandidates.add(node.getFile());
652:
653:                            addCandidates.add(node);
654:                            commitCandidates.add(node.getFile());
655:                        } else if (CommitOptions.ADD_TEXT == option
656:                                || CommitOptions.ADD_DIRECTORY == option) {
657:                            // assute no MIME property or startin gwith text
658:                            List<File> l = listUnmanagedParents(node);
659:                            Iterator<File> dit = l.iterator();
660:                            while (dit.hasNext()) {
661:                                if (support.isCanceled()) {
662:                                    return;
663:                                }
664:                                File file = dit.next();
665:                                addCandidates.add(new SvnFileNode(file));
666:                                commitCandidates.add(file);
667:                            }
668:                            if (support.isCanceled()) {
669:                                return;
670:                            }
671:                            addCandidates.add(node);
672:                            commitCandidates.add(node.getFile());
673:                        } else if (CommitOptions.COMMIT_REMOVE == option) {
674:                            removeCandidates.add(node.getFile());
675:                            commitCandidates.add(node.getFile());
676:                        } else if (CommitOptions.COMMIT == option) {
677:                            commitCandidates.add(node.getFile());
678:                        }
679:                    }
680:
681:                    // perform adds
682:                    performAdds(client, support, addCandidates);
683:                    if (support.isCanceled()) {
684:                        return;
685:                    }
686:
687:                    // TODO perform removes. especialy package removes where
688:                    // metadata must be replied from SvnMetadata (hold by FileSyatemHandler)
689:
690:                    // set binary mimetype and group commitCandidates by managed trees            
691:                    List<List<File>> managedTrees = getManagedTrees(client,
692:                            support, commitCandidates, binnaryCandidates);
693:                    if (support.isCanceled()) {
694:                        return;
695:                    }
696:
697:                    // finally commit            
698:                    for (Iterator<List<File>> itCandidates = managedTrees
699:                            .iterator(); itCandidates.hasNext();) {
700:
701:                        // one commit for each wc
702:                        List<File> commitList = itCandidates.next();
703:
704:                        // handle recursive commits - deleted and copied folders can't be commited non recursively
705:                        List<File> recursiveCommits = getRecursiveCommits(
706:                                commitList, removeCandidates);
707:                        if (recursiveCommits.size() > 0) {
708:                            // remove from the commits list all files which are supposed to be commited recursively 
709:                            // or are children from recursively commited folders
710:                            commitList.removeAll(getAllChildren(
711:                                    recursiveCommits, commitList));
712:
713:                            // commit recursively
714:                            File[] files = recursiveCommits
715:                                    .toArray(new File[recursiveCommits.size()]);
716:                            client.commit(files, message, true); // true = recursive
717:
718:                            if (support.isCanceled()) {
719:                                return;
720:                            }
721:                        }
722:
723:                        // commit the remaining files non recursively
724:                        if (commitList.size() > 0) {
725:
726:                            File[] files = commitList
727:                                    .toArray(new File[commitList.size()]);
728:                            client.commit(files, message, false); // false = non recursive
729:
730:                            if (support.isCanceled()) {
731:                                return;
732:                            }
733:                        }
734:
735:                        // update and refresh 
736:                        FileStatusCache cache = Subversion.getInstance()
737:                                .getStatusCache();
738:                        if (rootUpdate) {
739:                            File[] rootFiles = ctx.getRootFiles();
740:                            for (int i = 0; i < rootFiles.length; i++) {
741:                                client.update(rootFiles[i], SVNRevision.HEAD,
742:                                        false);
743:                            }
744:                            for (int i = 0; i < rootFiles.length; i++) {
745:                                cache
746:                                        .refresh(
747:                                                rootFiles[i],
748:                                                FileStatusCache.REPOSITORY_STATUS_UNKNOWN);
749:                            }
750:                        }
751:
752:                        // XXX it's probably already catched by cache's onNotify()
753:                        refreshFiles(cache, commitList);
754:                        if (support.isCanceled()) {
755:                            return;
756:                        }
757:                        refreshFiles(cache, recursiveCommits);
758:                        if (support.isCanceled()) {
759:                            return;
760:                        }
761:                    }
762:
763:                } catch (SVNClientException ex) {
764:                    support.annotate(ex);
765:                }
766:            }
767:
768:            /**
769:             * Groups files by distinct working copies and sets the binary mimetypes
770:             */
771:            private static List<List<File>> getManagedTrees(SvnClient client,
772:                    SvnProgressSupport support, Set<File> commitCandidates,
773:                    Set<File> binnaryCandidates) throws SVNClientException {
774:                FileStatusCache cache = Subversion.getInstance()
775:                        .getStatusCache();
776:                List<List<File>> managedTrees = new ArrayList<List<File>>();
777:                for (Iterator<File> itCommitCandidates = commitCandidates
778:                        .iterator(); itCommitCandidates.hasNext();) {
779:                    File commitCandidateFile = itCommitCandidates.next();
780:
781:                    // set MIME property application/octet-stream
782:                    if (binnaryCandidates.contains(commitCandidateFile)) {
783:                        ISVNProperty prop = client.propertyGet(
784:                                commitCandidateFile, ISVNProperty.MIME_TYPE);
785:                        if (prop != null) {
786:                            String s = prop.getValue();
787:                            if (s == null || s.startsWith("text/")) { // NOI18N
788:                                client.propertySet(commitCandidateFile,
789:                                        ISVNProperty.MIME_TYPE,
790:                                        "application/octet-stream", false); // NOI18N
791:                            }
792:                        } else {
793:                            client.propertySet(commitCandidateFile,
794:                                    ISVNProperty.MIME_TYPE,
795:                                    "application/octet-stream", false); // NOI18N
796:                        }
797:                    }
798:                    if (support.isCanceled()) {
799:                        return null;
800:                    }
801:
802:                    List<File> managedTreesList = null;
803:                    for (Iterator<List<File>> itManagedTrees = managedTrees
804:                            .iterator(); itManagedTrees.hasNext();) {
805:                        List<File> list = itManagedTrees.next();
806:                        File managedTreeFile = list.get(0);
807:
808:                        File base = SVNBaseDir.getRootDir(new File[] {
809:                                commitCandidateFile, managedTreeFile });
810:                        if (base != null) {
811:                            FileInformation status = cache.getStatus(base);
812:                            if ((status.getStatus() & FileInformation.STATUS_MANAGED) != 0) {
813:                                // found a list with files from the same working copy
814:                                managedTreesList = list;
815:                                break;
816:                            }
817:                        }
818:                        if (support.isCanceled()) {
819:                            return null;
820:                        }
821:                    }
822:                    if (managedTreesList == null) {
823:                        // no list for files from the same wc as commitCandidateFile created yet
824:                        managedTreesList = new ArrayList<File>();
825:                        managedTrees.add(managedTreesList);
826:                    }
827:                    managedTreesList.add(commitCandidateFile);
828:                }
829:
830:                return managedTrees;
831:            }
832:
833:            /**
834:             * Calls the svn add command on not yet added files
835:             */
836:            private static void performAdds(SvnClient client,
837:                    SvnProgressSupport support, List<SvnFileNode> addCandidates)
838:                    throws SVNClientException {
839:                List<File> addFiles = new ArrayList<File>();
840:                List<File> addDirs = new ArrayList<File>();
841:                // XXX waht if user denied directory add but wants to add a file in it?
842:                Iterator<SvnFileNode> it = addCandidates.iterator();
843:                while (it.hasNext()) {
844:                    if (support.isCanceled()) {
845:                        return;
846:                    }
847:                    SvnFileNode svnFileNode = it.next();
848:                    File file = svnFileNode.getFile();
849:                    if (file.isDirectory()) {
850:                        addDirs.add(file);
851:                    } else if (file.isFile()) {
852:                        addFiles.add(file);
853:                    }
854:                }
855:                if (support.isCanceled()) {
856:                    return;
857:                }
858:
859:                Iterator<File> itFiles = addDirs.iterator();
860:                List<File> dirsToAdd = new ArrayList<File>();
861:                while (itFiles.hasNext()) {
862:                    File dir = itFiles.next();
863:                    if (!dirsToAdd.contains(dir)) {
864:                        dirsToAdd.add(dir);
865:                    }
866:                }
867:                if (dirsToAdd.size() > 0) {
868:                    client.addFile(dirsToAdd
869:                            .toArray(new File[dirsToAdd.size()]), false);
870:                }
871:                if (support.isCanceled()) {
872:                    return;
873:                }
874:
875:                if (addFiles.size() > 0) {
876:                    client.addFile(addFiles.toArray(new File[addFiles.size()]),
877:                            false);
878:                }
879:            }
880:
881:            /**
882:             * Returns all files which have to be commited recursively (deleted and copied folders)
883:             */
884:            private static List<File> getRecursiveCommits(
885:                    List<File> nonRecursiveComits, List<File> removeCandidates) {
886:                FileStatusCache cache = Subversion.getInstance()
887:                        .getStatusCache();
888:                List<File> recursiveCommits = new ArrayList<File>();
889:
890:                // 1. if there is at least one directory which isn't removed or copied
891:                //    we have to commit it nonrecursively ...           
892:                boolean nonRecursiveDirs = false;
893:                for (File file : nonRecursiveComits) {
894:                    if (file.isDirectory()
895:                            && !(removeCandidates.contains(file) || cache
896:                                    .getStatus(file).getEntry(file).isCopied())) {
897:                        nonRecursiveDirs = true;
898:                        break;
899:                    }
900:                }
901:                if (!nonRecursiveDirs) {
902:                    // 2. ... otherwise we may commit all files recursivelly
903:                    recursiveCommits.addAll(recursiveCommits);
904:                    recursiveCommits.addAll(nonRecursiveComits);
905:                } else {
906:                    // 3. ... well, this is the worst case. we have folders which were deleted or copied 
907:                    //        and such have to be commited recursively (svn restriction). On the other hand, 
908:                    //        there are also folders which have to be commited and doing it recursivelly 
909:                    //        could cause that the commit would also apply to files which because of exclusion or 
910:                    //        the (bloody) flat-folder loginc aren't supposed to be commited at all =>
911:                    //        => the commit has to be split in two parts. 
912:                    for (File file : nonRecursiveComits) {
913:                        if (file.isDirectory()
914:                                && (removeCandidates.contains(file) || cache
915:                                        .getStatus(file).getEntry(file)
916:                                        .isCopied())) {
917:                            recursiveCommits.add(file);
918:                        }
919:                    }
920:                }
921:
922:                return recursiveCommits;
923:            }
924:
925:            /**
926:             * Returns all files from the children list which have a parent in or are equal to a folder from the parents list 
927:             */
928:            private static List<File> getAllChildren(List<File> parents,
929:                    List<File> children) {
930:                List<File> ret = new ArrayList<File>();
931:                if (parents.size() > 0) {
932:                    for (File child : children) {
933:                        File parent = child;
934:                        while (parent != null) {
935:                            if (parents.contains(parent)) {
936:                                ret.add(child);
937:                            }
938:                            parent = parent.getParentFile();
939:                        }
940:                    }
941:                }
942:                return ret;
943:            }
944:
945:            private static void refreshFiles(FileStatusCache cache,
946:                    List<File> files) {
947:                for (File file : files) {
948:                    cache.refresh(file,
949:                            FileStatusCache.REPOSITORY_STATUS_UNKNOWN);
950:                }
951:            }
952:
953:            private static List<File> listUnmanagedParents(SvnFileNode node) {
954:                List<File> unmanaged = new ArrayList<File>();
955:                File file = node.getFile();
956:                File parent = file.getParentFile();
957:                while (true) {
958:                    if (new File(parent, ".svn/entries").canRead()
959:                            || new File(parent, "_svn/entries").canRead()) { // NOI18N
960:                        break;
961:                    }
962:                    unmanaged.add(0, parent);
963:                    parent = parent.getParentFile();
964:                    if (parent == null) {
965:                        break;
966:                    }
967:                }
968:
969:                List<File> ret = new ArrayList<File>();
970:                Iterator<File> it = unmanaged.iterator();
971:                while (it.hasNext()) {
972:                    File un = it.next();
973:                    ret.add(un);
974:                }
975:
976:                return ret;
977:            }
978:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.