KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > versioning > system > cvss > ui > actions > project > AddToRepositoryAction


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.versioning.system.cvss.ui.actions.project;
21
22 import org.openide.util.actions.NodeAction;
23 import org.openide.util.*;
24 import org.openide.nodes.Node;
25 import org.openide.filesystems.FileObject;
26 import org.openide.filesystems.FileUtil;
27 import org.openide.*;
28 import org.openide.loaders.DataObject;
29 import org.openide.loaders.DataShadow;
30 import org.netbeans.api.project.*;
31 import org.netbeans.api.queries.SharabilityQuery;
32 import org.netbeans.modules.versioning.system.cvss.CvsModuleConfig;
33 import org.netbeans.modules.versioning.system.cvss.ui.wizards.RepositoryStep;
34 import org.netbeans.modules.versioning.system.cvss.ui.wizards.AbstractStep;
35 import org.netbeans.modules.versioning.system.cvss.ui.selectors.ModuleSelector;
36 import org.netbeans.modules.versioning.system.cvss.FileInformation;
37 import org.netbeans.modules.versioning.system.cvss.FileStatusCache;
38 import org.netbeans.modules.versioning.system.cvss.CvsVersioningSystem;
39 import org.netbeans.modules.versioning.system.cvss.ExecutorGroup;
40 import org.netbeans.lib.cvsclient.command.importcmd.ImportCommand;
41 import org.netbeans.lib.cvsclient.command.GlobalOptions;
42 import org.netbeans.lib.cvsclient.CVSRoot;
43 import org.netbeans.spi.project.ui.support.ProjectChooser;
44
45 import javax.swing.*;
46 import javax.swing.event.DocumentListener JavaDoc;
47 import javax.swing.event.DocumentEvent JavaDoc;
48 import javax.swing.event.ChangeListener JavaDoc;
49 import javax.swing.event.ChangeEvent JavaDoc;
50 import java.io.*;
51 import java.util.*;
52 import java.text.MessageFormat JavaDoc;
53 import java.awt.event.ActionListener JavaDoc;
54 import java.awt.event.ActionEvent JavaDoc;
55
56 /**
57  * Imports folder into CVS repository. It's enabled on Nodes that represent:
58  * <ul>
59  * <li>project root directory, parent of all necessary
60  * project data and metadata.
61  * <li>folders that are not a part on any project
62  * </ul>
63  * It's minimalitics attempt to assure
64  * that the project can be reopend after checkout.
65  * It also simplifies implemenattion avoiding huge
66  * import mapping wizard for projects with external
67  * data folders.
68  *
69  * <p>Before actual CVS <tt>import</tt> it recursively scans
70  * imported context and prepares <tt>.cvsignore</tt> files.
71  * After <tt>import</tt> it optionally turns imported context
72  * into versioned using <tt>checkout</tt> and copying respective
73  * CVS metadata.
74  *
75  * @author Petr Kuzel
76  */

77 public final class AddToRepositoryAction extends NodeAction implements ChangeListener JavaDoc {
78
79     private static final String JavaDoc RECENT_ROOTS = "addToRepositoryAction.recentRoots";
80
81     private WizardDescriptor wizard;
82
83     private WizardDescriptor.Iterator wizardIterator;
84
85     private RepositoryStep repositoryStep;
86     private ImportStep importStep;
87
88     public AddToRepositoryAction() {
89         setIcon(null);
90         putValue("noIconInMenu", Boolean.TRUE); // NOI18N
91
}
92
93     public String JavaDoc getName() {
94         return NbBundle.getMessage(AddToRepositoryAction.class, "BK0006");
95     }
96
97     public HelpCtx getHelpCtx() {
98         return null;
99     }
100
101     protected boolean enable(Node[] nodes) {
102         if (nodes.length == 1) {
103             FileStatusCache cache = CvsVersioningSystem.getInstance().getStatusCache();
104             File dir = lookupImportDirectory(nodes[0]);
105             if (dir != null && dir.isDirectory()) {
106                 FileInformation status = cache.getStatus(dir);
107                 // mutually exclusive enablement logic with commit
108
if ((status.getStatus() & FileInformation.STATUS_MANAGED) == 0) {
109                     // do not allow to import partial/nonatomic project, all must lie under imported common root
110
FileObject fo = FileUtil.toFileObject(dir);
111                     Project p = FileOwnerQuery.getOwner(fo);
112                     if (p == null) {
113                         return true;
114                     }
115                     FileObject projectDir = p.getProjectDirectory();
116                     return FileUtil.isParentOf(projectDir, fo) == false;
117                 }
118             }
119         }
120         return false;
121     }
122
123     protected void performAction(Node[] nodes) {
124         if (nodes.length == 1) {
125             final File importDirectory = lookupImportDirectory(nodes[0]);
126             if (importDirectory != null) {
127
128                 // try to detect some resonable defaults for cvs root and repositoryStep
129

130                 File parent = importDirectory.getParentFile();
131                 File parent_cvsRoot = new File(parent, "CVS/Root"); // NOI18N
132
File parent_cvsRepo = new File(parent, "CVS/Repository"); // NOI18N
133
String JavaDoc cvsRoot = null;
134                 String JavaDoc cvsRepository = null;
135                 if (parent_cvsRepo.isFile() && parent_cvsRoot.isFile()) {
136                     BufferedReader r = null;
137                     try {
138                         r = new BufferedReader((new FileReader(parent_cvsRoot)));
139                         cvsRoot = r.readLine();
140                     } catch (IOException e) {
141                         ErrorManager err = ErrorManager.getDefault();
142                         err.annotate(e, NbBundle.getMessage(AddToRepositoryAction.class, "BK0016"));
143                         err.notify(e);
144                     } finally {
145                         if (r != null) {
146                             try {
147                                 r.close();
148                             } catch (IOException alreadyClosed) {
149                             }
150                         }
151                     }
152
153                     try {
154                         r = new BufferedReader((new FileReader(parent_cvsRepo)));
155                         cvsRepository = r.readLine();
156                     } catch (IOException e) {
157                         ErrorManager err = ErrorManager.getDefault();
158                         err.annotate(e, NbBundle.getMessage(AddToRepositoryAction.class, "BK0017"));
159                         err.notify(e);
160                     } finally {
161                         if (r != null) {
162                             try {
163                                 r.close();
164                             } catch (IOException alreadyClosed) {
165                             }
166                         }
167                     }
168                 }
169
170                 String JavaDoc prefRoot;
171                 if (cvsRoot != null) {
172                     prefRoot = cvsRoot;
173                 } else {
174                     prefRoot = NbBundle.getMessage(AddToRepositoryAction.class, "BK0008");
175                 }
176
177                 String JavaDoc prefModule;
178                 if (cvsRepository != null) {
179                     prefModule = cvsRepository + "/" + importDirectory.getName(); // NOI18N
180
} else {
181                     prefModule = importDirectory.getName();
182                 }
183
184                 wizardIterator = panelIterator(prefRoot, prefModule, importDirectory.getAbsolutePath());
185                 wizard = new WizardDescriptor(wizardIterator);
186                 wizard.putProperty("WizardPanel_contentData", // NOI18N
187
new String JavaDoc[] {
188                             NbBundle.getMessage(AddToRepositoryAction.class, "BK0015"),
189                             NbBundle.getMessage(AddToRepositoryAction.class, "BK0014")
190                         }
191                 );
192                 wizard.putProperty("WizardPanel_contentDisplayed", Boolean.TRUE); // NOI18N
193
wizard.putProperty("WizardPanel_autoWizardStyle", Boolean.TRUE); // NOI18N
194
wizard.putProperty("WizardPanel_contentNumbered", Boolean.TRUE); // NOI18N
195
wizard.setTitleFormat(new MessageFormat JavaDoc("{0}")); // NOI18N
196
String JavaDoc title = NbBundle.getMessage(AddToRepositoryAction.class, "BK0007");
197                 wizard.setTitle(title);
198
199                 Object JavaDoc result = DialogDisplayer.getDefault().notify(wizard);
200                 if (result == DialogDescriptor.OK_OPTION) {
201                     RequestProcessor.getDefault().post(new Runnable JavaDoc() {
202                         public void run() {
203                             async(importDirectory);
204                         }
205                     });
206                 }
207             }
208         }
209     }
210
211     private void async(File importDirectory) {
212         boolean checkout = importStep.getCheckout();
213         String JavaDoc logMessage = importStep.getMessage();
214         String JavaDoc module = importStep.getModule();
215         String JavaDoc vendorTag = "default_vendor"; // NOI18N
216
String JavaDoc releaseTag = "default_release"; // NOI18N
217
String JavaDoc selectedRoot = repositoryStep.getCvsRoot();
218         String JavaDoc folder = importStep.getFolder();
219         File dir = new File(folder);
220
221         org.netbeans.modules.versioning.util.Utils.insert(CvsModuleConfig.getDefault().getPreferences(), RECENT_ROOTS, selectedRoot, 8);
222
223         ExecutorGroup group = new ExecutorGroup(NbBundle.getMessage(AddToRepositoryAction.class, "BK0019"));
224         try {
225             group.progress(NbBundle.getMessage(AddToRepositoryAction.class, "BK0020"));
226             final Thread JavaDoc thread = Thread.currentThread();
227             group.addCancellable(new Cancellable() {
228                 public boolean cancel() {
229                     thread.interrupt();
230                     return true;
231                 }
232             });
233             prepareIgnore(dir);
234         } catch (IOException e) {
235             group.executed();
236             ErrorManager err = ErrorManager.getDefault();
237             err.annotate(e, NbBundle.getMessage(AddToRepositoryAction.class, "BK0021"));
238             err.notify(e);
239             return;
240         }
241
242         GlobalOptions gtx = CvsVersioningSystem.createGlobalOptions();
243         gtx.setCVSRoot(selectedRoot);
244         ImportCommand importCommand = new ImportCommand();
245         importCommand.setModule(module);
246         importCommand.setLogMessage(logMessage);
247         importCommand.setVendorTag(vendorTag);
248         importCommand.setReleaseTag(releaseTag);
249         importCommand.setImportDirectory(importDirectory.getPath());
250
251         new ImportExecutor(importCommand, gtx, checkout, folder, group); // joins the group
252
group.execute();
253     }
254
255     public boolean cancel() {
256
257         return true;
258     }
259
260     private File lookupImportDirectory(Node node) {
261         File importDirectory = null;
262         Project project = (Project) node.getLookup().lookup(Project.class);
263         if (project != null) {
264             Sources sources = ProjectUtils.getSources(project);
265             SourceGroup[] groups = sources.getSourceGroups(Sources.TYPE_GENERIC);
266             if (groups.length == 1) {
267                 FileObject root = groups[0].getRootFolder();
268                 importDirectory = FileUtil.toFile(root);
269             } else {
270                 importDirectory = FileUtil.toFile(project.getProjectDirectory());
271             }
272         } else {
273             FileObject fo = null;
274             Collection fileObjects = node.getLookup().lookup(new Lookup.Template(FileObject.class)).allInstances();
275             if (fileObjects.size() > 0) {
276                 fo = (FileObject) fileObjects.iterator().next();
277             } else {
278                 DataObject dataObject = (DataObject) node.getCookie(DataObject.class);
279                 if (dataObject instanceof DataShadow) {
280                     dataObject = ((DataShadow) dataObject).getOriginal();
281                 }
282                 if (dataObject != null) {
283                     fo = dataObject.getPrimaryFile();
284                 }
285             }
286
287             if (fo != null) {
288                 File f = FileUtil.toFile(fo);
289                 if (f != null && f.isDirectory()) {
290                     importDirectory = f;
291                 }
292             }
293         }
294         return importDirectory;
295     }
296
297     private WizardDescriptor.Iterator panelIterator(String JavaDoc root, String JavaDoc module, String JavaDoc folder) {
298         repositoryStep = new RepositoryStep();
299         repositoryStep.initPreferedCvsRoot(root);
300         repositoryStep.addChangeListener(this);
301         importStep = new ImportStep(module, folder);
302         importStep.addChangeListener(this);
303
304         final WizardDescriptor.Panel[] panels = new WizardDescriptor.Panel[2];
305         panels[0] = repositoryStep;
306         panels[1] = importStep;
307
308         WizardDescriptor.ArrayIterator ret = new WizardDescriptor.ArrayIterator(panels) {
309             public WizardDescriptor.Panel current() {
310                 WizardDescriptor.Panel ret = super.current();
311                 for (int i = 0; i<panels.length; i++) {
312                     if (panels[i] == ret) {
313                         wizard.putProperty("WizardPanel_contentSelectedIndex", new Integer JavaDoc(i)); // NOI18N
314
}
315                 }
316                 return ret;
317             }
318         };
319         return ret;
320     }
321
322     private void setErrorMessage(String JavaDoc msg) {
323         if (wizard != null) {
324             wizard.putProperty("WizardPanel_errorMessage", msg); // NOI18N
325
}
326     }
327
328     public void stateChanged(ChangeEvent JavaDoc e) {
329         AbstractStep step = (AbstractStep) wizardIterator.current();
330         setErrorMessage(step.getErrorMessage());
331     }
332
333     class ImportStep extends AbstractStep implements ActionListener JavaDoc {
334         private final String JavaDoc module;
335         private final String JavaDoc folder;
336         private ImportPanel importPanel;
337
338         public ImportStep(String JavaDoc module, String JavaDoc folder) {
339             this.module = module;
340             this.folder = folder;
341         }
342
343         public HelpCtx getHelp() {
344             return new HelpCtx(ImportStep.class);
345         }
346
347         protected JComponent createComponent() {
348             importPanel = new ImportPanel();
349             importPanel.moduleTextField.setText(module);
350             importPanel.folderTextField.setText(folder);
351
352             // user input validation
353
DocumentListener JavaDoc validation = new DocumentListener JavaDoc() {
354                 public void changedUpdate(DocumentEvent JavaDoc e) {
355                 }
356                 public void insertUpdate(DocumentEvent JavaDoc e) {
357                     String JavaDoc s = checkInput(importPanel);
358                     if (s == null) {
359                         valid();
360                     } else {
361                         invalid(s);
362                     }
363                 }
364                 public void removeUpdate(DocumentEvent JavaDoc e) {
365                     String JavaDoc s = checkInput(importPanel);
366                     if (s == null) {
367                         valid();
368                     } else {
369                         invalid(s);
370                     }
371                 }
372             };
373             importPanel.moduleTextField.getDocument().addDocumentListener(validation);
374             importPanel.commentTextArea.getDocument().addDocumentListener(validation);
375             importPanel.folderTextField.getDocument().addDocumentListener(validation);
376             importPanel.folderButton.addActionListener(this);
377             importPanel.moduleButton.addActionListener(this);
378
379             String JavaDoc s = checkInput(importPanel);
380             if (s == null) {
381                 valid();
382             } else {
383                 invalid(s);
384             }
385
386             return importPanel;
387         }
388
389         protected void validateBeforeNext() {
390         }
391
392         public boolean getCheckout() {
393             return importPanel.checkoutCheckBox.isSelected();
394         }
395
396         public String JavaDoc getMessage() {
397             return importPanel.commentTextArea.getText();
398         }
399
400         public String JavaDoc getModule() {
401             return importPanel.moduleTextField.getText();
402         }
403
404         public String JavaDoc getFolder() {
405             return importPanel.folderTextField.getText();
406         }
407
408         /**
409          * Returns file to be initaly used.
410          * <ul>
411          * <li>first is takes text in workTextField
412          * <li>then recent project folder
413          * <li>finally <tt>user.home</tt>
414          * <ul>
415          */

416         private File defaultWorkingDirectory() {
417             File defaultDir = null;
418             String JavaDoc current = importPanel.folderTextField.getText();
419             if (current != null && !(current.trim().equals(""))) { // NOI18N
420
File currentFile = new File(current);
421                 while (currentFile != null && currentFile.exists() == false) {
422                     currentFile = currentFile.getParentFile();
423                 }
424                 if (currentFile != null) {
425                     if (currentFile.isFile()) {
426                         defaultDir = currentFile.getParentFile();
427                     } else {
428                         defaultDir = currentFile;
429                     }
430                 }
431             }
432
433             if (defaultDir == null) {
434                 File projectFolder = ProjectChooser.getProjectsFolder();
435                 if (projectFolder.exists() && projectFolder.isDirectory()) {
436                     defaultDir = projectFolder;
437                 }
438             }
439
440             if (defaultDir == null) {
441                 defaultDir = new File(System.getProperty("user.home")); // NOI18N
442
}
443
444             return defaultDir;
445         }
446
447         public void actionPerformed(ActionEvent JavaDoc e) {
448             if (e.getSource() == importPanel.folderButton) {
449                 File defaultDir = defaultWorkingDirectory();
450                 JFileChooser fileChooser = new JFileChooser(defaultDir);
451                 fileChooser.setDialogTitle(NbBundle.getMessage(AddToRepositoryAction.class, "BK1017"));
452                 fileChooser.setMultiSelectionEnabled(false);
453                 javax.swing.filechooser.FileFilter JavaDoc[] old = fileChooser.getChoosableFileFilters();
454                 for (int i = 0; i < old.length; i++) {
455                     javax.swing.filechooser.FileFilter JavaDoc fileFilter = old[i];
456                     fileChooser.removeChoosableFileFilter(fileFilter);
457
458                 }
459                 fileChooser.addChoosableFileFilter(new javax.swing.filechooser.FileFilter JavaDoc() {
460                     public boolean accept(File f) {
461                         return f.isDirectory();
462                     }
463                     public String JavaDoc getDescription() {
464                         return NbBundle.getMessage(AddToRepositoryAction.class, "BK1018");
465                     }
466                 });
467                 fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
468                 fileChooser.showDialog(importPanel, NbBundle.getMessage(AddToRepositoryAction.class, "BK1019"));
469                 File f = fileChooser.getSelectedFile();
470                 if (f != null) {
471                     importPanel.folderTextField.setText(f.getAbsolutePath());
472                 }
473             } else if (e.getSource() == importPanel.moduleButton) {
474                 ModuleSelector selector = new ModuleSelector();
475                 CVSRoot root = CVSRoot.parse(repositoryStep.getCvsRoot());
476                 String JavaDoc path = selector.selectRepositoryPath(root);
477                 if (path != null) {
478                     importPanel.moduleTextField.setText(path);
479                 }
480             }
481         }
482     }
483
484     private static String JavaDoc checkInput(ImportPanel importPanel) {
485         boolean valid = true;
486
487         File file = new File(importPanel.folderTextField.getText());
488         valid &= file.isDirectory();
489         if (!valid) return NbBundle.getMessage(AddToRepositoryAction.class, "BK0022");
490
491         valid &= (new File(file, "CVS").exists()) == false; // NOI18N
492
if (!valid) return NbBundle.getMessage(AddToRepositoryAction.class, "BK0023");
493
494         valid &= importPanel.commentTextArea.getText().trim().length() > 0;
495         if (!valid) return NbBundle.getMessage(AddToRepositoryAction.class, "BK0024");
496
497         String JavaDoc module = importPanel.moduleTextField.getText().trim();
498         valid &= module.length() > 0;
499         if (!valid) return NbBundle.getMessage(AddToRepositoryAction.class, "BK0025");
500         valid &= module.indexOf(" ") == -1; // NOI18N // NOI18N
501
valid &= ".".equals(module.trim()) == false; // NOI18N
502
if (!valid) return NbBundle.getMessage(AddToRepositoryAction.class, "BK0026");
503
504         return null;
505     }
506
507     /**
508      * @return false on Thread.interrupted i.e. user cancel.
509      */

510     private boolean prepareIgnore(File dir) throws IOException {
511         File[] projectMeta = dir.listFiles();
512         Set ignored = new HashSet();
513         for (int i = 0; i < projectMeta.length; i++) {
514             if (Thread.interrupted()) {
515                 return false;
516             }
517             File file = projectMeta[i];
518             String JavaDoc name = file.getName();
519             int sharability = SharabilityQuery.getSharability(file);
520             if (sharability == SharabilityQuery.NOT_SHARABLE) {
521                 if (".cvsignore".equals(name) == false) { // NOI18N
522
ignored.add(name);
523                 }
524             } else if (sharability == SharabilityQuery.MIXED) {
525                 assert file.isDirectory() : file;
526                 prepareIgnore(file);
527             }
528         }
529
530         if (ignored.size() > 0) {
531             File cvsIgnore = new File(dir, ".cvsignore"); // NOI18N
532
OutputStream out = null;
533             try {
534                 out = new FileOutputStream(cvsIgnore);
535                 PrintWriter pw = new PrintWriter(out);
536                 Iterator it = ignored.iterator();
537                 while (it.hasNext()) {
538                     String JavaDoc name = (String JavaDoc) it.next();
539                     pw.println(name);
540                 }
541                 pw.close();
542             } finally {
543                 if (out != null) {
544                     try {
545                         out.close();
546                     } catch (IOException alreadyClosed) {
547                     }
548                 }
549             }
550         }
551         return true;
552     }
553
554     protected boolean asynchronous() {
555         return false;
556     }
557
558 }
559
Popular Tags