KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > subversion > Annotator


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.subversion;
21
22 import org.netbeans.modules.subversion.ui.copy.*;
23 import org.netbeans.modules.subversion.ui.ignore.IgnoreAction;
24 import org.netbeans.modules.subversion.ui.status.StatusAction;
25 import org.netbeans.modules.subversion.ui.commit.CommitAction;
26 import org.netbeans.modules.subversion.ui.update.*;
27 import org.netbeans.modules.subversion.ui.diff.DiffAction;
28 import org.netbeans.modules.subversion.ui.diff.ExportDiffAction;
29 import org.netbeans.modules.subversion.ui.blame.BlameAction;
30 import org.netbeans.modules.subversion.ui.history.SearchHistoryAction;
31 import org.netbeans.modules.subversion.ui.project.ImportAction;
32 import org.netbeans.modules.subversion.ui.checkout.CheckoutAction;
33 import org.openide.util.actions.SystemAction;
34 import org.openide.util.NbBundle;
35 import org.openide.util.Utilities;
36 import org.openide.util.Lookup;
37 import org.openide.util.lookup.Lookups;
38 import org.openide.ErrorManager;
39 import org.openide.nodes.Node;
40 import org.netbeans.modules.subversion.util.SvnUtils;
41 import org.netbeans.modules.versioning.util.FlatFolder;
42 import org.netbeans.modules.versioning.util.Utils;
43 import org.netbeans.modules.versioning.spi.VCSContext;
44 import org.netbeans.modules.versioning.spi.VCSAnnotator;
45 import org.netbeans.api.project.Project;
46 import javax.swing.*;
47 import java.util.*;
48 import java.util.List JavaDoc;
49 import java.util.regex.Pattern JavaDoc;
50 import java.text.MessageFormat JavaDoc;
51 import java.io.File JavaDoc;
52 import java.awt.*;
53 import java.lang.reflect.Field JavaDoc;
54 import org.netbeans.modules.subversion.client.SvnClient;
55 import org.netbeans.modules.subversion.ui.properties.SvnPropertiesAction;
56 import org.netbeans.modules.subversion.ui.relocate.RelocateAction;
57 import org.netbeans.modules.versioning.util.SystemActionBridge;
58 import org.tigris.subversion.svnclientadapter.*;
59
60 /**
61  * Annotates names for display in Files and Projects view (and possible elsewhere). Uses
62  * Filesystem support for this feature (to be replaced later in Core by something more generic).
63  *
64  * @author Maros Sandor
65  */

66 public class Annotator {
67
68     private static MessageFormat JavaDoc uptodateFormat = getFormat("uptodateFormat"); // NOI18N
69
private static MessageFormat JavaDoc newLocallyFormat = getFormat("newLocallyFormat"); // NOI18N
70
private static MessageFormat JavaDoc addedLocallyFormat = getFormat("addedLocallyFormat"); // NOI18N
71
private static MessageFormat JavaDoc modifiedLocallyFormat = getFormat("modifiedLocallyFormat"); // NOI18N
72
private static MessageFormat JavaDoc removedLocallyFormat = getFormat("removedLocallyFormat"); // NOI18N
73
private static MessageFormat JavaDoc deletedLocallyFormat = getFormat("deletedLocallyFormat"); // NOI18N
74
private static MessageFormat JavaDoc newInRepositoryFormat = getFormat("newInRepositoryFormat"); // NOI18N
75
private static MessageFormat JavaDoc modifiedInRepositoryFormat = getFormat("modifiedInRepositoryFormat"); // NOI18N
76
private static MessageFormat JavaDoc removedInRepositoryFormat = getFormat("removedInRepositoryFormat"); // NOI18N
77
private static MessageFormat JavaDoc conflictFormat = getFormat("conflictFormat"); // NOI18N
78
private static MessageFormat JavaDoc mergeableFormat = getFormat("mergeableFormat"); // NOI18N
79
private static MessageFormat JavaDoc excludedFormat = getFormat("excludedFormat"); // NOI18N
80

81     private static final int STATUS_TEXT_ANNOTABLE = FileInformation.STATUS_NOTVERSIONED_EXCLUDED |
82             FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY | FileInformation.STATUS_VERSIONED_UPTODATE |
83             FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY | FileInformation.STATUS_VERSIONED_CONFLICT |
84             FileInformation.STATUS_VERSIONED_REMOVEDLOCALLY | FileInformation.STATUS_VERSIONED_DELETEDLOCALLY |
85             FileInformation.STATUS_VERSIONED_ADDEDLOCALLY;
86
87     private static final Pattern JavaDoc lessThan = Pattern.compile("<"); // NOI18N
88

89     public static String JavaDoc ANNOTATION_REVISION = "revision";
90     public static String JavaDoc ANNOTATION_STATUS = "status";
91     public static String JavaDoc ANNOTATION_FOLDER = "folder";
92     public static String JavaDoc ANNOTATION_MIME_TYPE = "mime_type";
93     
94     public static String JavaDoc[] LABELS = new String JavaDoc[] {ANNOTATION_REVISION, ANNOTATION_STATUS, ANNOTATION_FOLDER, ANNOTATION_MIME_TYPE};
95     
96     private final FileStatusCache cache;
97     private MessageFormat JavaDoc format;
98     private String JavaDoc emptyFormat;
99             
100     private boolean mimeTypeFlag;
101
102     Annotator(Subversion svn) {
103         this.cache = svn.getStatusCache();
104         initDefaults();
105     }
106
107     private void initDefaults() {
108         Field JavaDoc [] fields = Annotator.class.getDeclaredFields();
109         for (int i = 0; i < fields.length; i++) {
110             String JavaDoc name = fields[i].getName();
111             if (name.endsWith("Format")) { // NOI18N
112
initDefaultColor(name.substring(0, name.length() - 6));
113             }
114         }
115         refresh();
116     }
117
118     public void refresh() {
119         String JavaDoc string = SvnModuleConfig.getDefault().getAnnotationFormat(); //System.getProperty("netbeans.experimental.svn.ui.statusLabelFormat"); // NOI18N
120
if (string != null && !string.trim().equals("")) {
121             mimeTypeFlag = string.indexOf("{mime_type}") > -1;
122             string = string.replaceAll("\\{revision\\}", "\\{0\\}"); // NOI18N
123
string = string.replaceAll("\\{status\\}", "\\{1\\}"); // NOI18N
124
string = string.replaceAll("\\{folder\\}", "\\{2\\}"); // NOI18N
125
string = string.replaceAll("\\{mime_type\\}", "\\{3\\}"); // NOI18N
126
format = new MessageFormat JavaDoc(string);
127             emptyFormat = format.format(new String JavaDoc[] {"", "", "", ""} , new StringBuffer JavaDoc(), null).toString().trim();
128         }
129     }
130     
131     private void initDefaultColor(String JavaDoc name) {
132         String JavaDoc color = System.getProperty("svn.color." + name); // NOI18N
133
if (color == null) return;
134         setAnnotationColor(name, color);
135     }
136
137     /**
138      * Changes annotation color of files.
139      *
140      * @param name name of the color to change. Can be one of:
141      * newLocally, addedLocally, modifiedLocally, removedLocally, deletedLocally, newInRepository, modifiedInRepository,
142      * removedInRepository, conflict, mergeable, excluded.
143      * @param colorString new color in the format: 4455AA (RGB hexadecimal)
144      */

145     private void setAnnotationColor(String JavaDoc name, String JavaDoc colorString) {
146         try {
147             Field JavaDoc field = Annotator.class.getDeclaredField(name + "Format"); // NOI18N
148
MessageFormat JavaDoc format = new MessageFormat JavaDoc("<font color=\"" + colorString + "\">{0}</font><font color=\"#999999\">{1}</font>"); // NOI18N
149
field.set(null, format);
150         } catch (Exception JavaDoc e) {
151             throw new IllegalArgumentException JavaDoc("Invalid color name"); // NOI18N
152
}
153     }
154     
155     /**
156      * Adds rendering attributes to an arbitrary String based on a SVN status. The name is usually a file or folder
157      * display name and status is usually its SVN status as reported by FileStatusCache.
158      *
159      * @param name name to annotate
160      * @param info status that an object with the given name has
161      * @param file file this annotation belongs to. It is used to determine sticky tags for textual annotations. Pass
162      * null if you do not want textual annotations to appear in returned markup
163      * @return String html-annotated name that can be used in Swing controls that support html rendering. Note: it may
164      * also return the original name String
165      */

166     public String JavaDoc annotateNameHtml(String JavaDoc name, FileInformation info, File JavaDoc file) {
167         name = htmlEncode(name);
168         int status = info.getStatus();
169         String JavaDoc textAnnotation;
170         String JavaDoc textAnnotationFormat = SvnModuleConfig.getDefault().getPreferences().get(SvnModuleConfig.PROP_TEXT_ANNOTATIONS_FORMAT, null);
171         if (textAnnotationFormat != null && file != null && (status & STATUS_TEXT_ANNOTABLE) != 0) {
172             if (format != null) {
173                 textAnnotation = formatAnnotation(info, file);
174             } else {
175                 String JavaDoc sticky = SvnUtils.getCopy(file);
176                 if (status == FileInformation.STATUS_VERSIONED_UPTODATE && sticky == null) {
177                     textAnnotation = ""; // NOI18N
178
} else if (status == FileInformation.STATUS_VERSIONED_UPTODATE) {
179                     textAnnotation = " [" + sticky + "]"; // NOI18N
180
} else if (sticky == null) {
181                     String JavaDoc statusText = info.getShortStatusText();
182                     if(!statusText.equals("")) {
183                         textAnnotation = " [" + info.getShortStatusText() + "]"; // NOI18N
184
} else {
185                         textAnnotation = "";
186                     }
187                 } else {
188                     textAnnotation = " [" + info.getShortStatusText() + "; " + sticky + "]"; // NOI18N
189
}
190             }
191         } else {
192             textAnnotation = ""; // NOI18N
193
}
194         if (textAnnotation.length() > 0) {
195             textAnnotation = NbBundle.getMessage(Annotator.class, "textAnnotation", textAnnotation);
196         }
197
198         // aligned with SvnUtils.getComparableStatus
199

200         if (0 != (status & FileInformation.STATUS_VERSIONED_CONFLICT)) {
201             return conflictFormat.format(new Object JavaDoc [] { name, textAnnotation });
202         } else if (0 != (status & FileInformation.STATUS_VERSIONED_MERGE)) {
203             return mergeableFormat.format(new Object JavaDoc [] { name, textAnnotation });
204         } else if (0 != (status & FileInformation.STATUS_VERSIONED_DELETEDLOCALLY)) {
205             return deletedLocallyFormat.format(new Object JavaDoc [] { name, textAnnotation });
206         } else if (0 != (status & FileInformation.STATUS_VERSIONED_REMOVEDLOCALLY)) {
207             return removedLocallyFormat.format(new Object JavaDoc [] { name, textAnnotation });
208         } else if (0 != (status & FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY)) {
209             return newLocallyFormat.format(new Object JavaDoc [] { name, textAnnotation });
210         } else if (0 != (status & FileInformation.STATUS_VERSIONED_ADDEDLOCALLY)) {
211             return addedLocallyFormat.format(new Object JavaDoc [] { name, textAnnotation });
212         } else if (0 != (status & FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY)) {
213             return modifiedLocallyFormat.format(new Object JavaDoc [] { name, textAnnotation });
214
215         // repository changes - lower annotator priority
216

217         } else if (0 != (status & FileInformation.STATUS_VERSIONED_REMOVEDINREPOSITORY)) {
218             return removedInRepositoryFormat.format(new Object JavaDoc [] { name, textAnnotation });
219         } else if (0 != (status & FileInformation.STATUS_VERSIONED_NEWINREPOSITORY)) {
220             return newInRepositoryFormat.format(new Object JavaDoc [] { name, textAnnotation });
221         } else if (0 != (status & FileInformation.STATUS_VERSIONED_MODIFIEDINREPOSITORY)) {
222             return modifiedInRepositoryFormat.format(new Object JavaDoc [] { name, textAnnotation });
223         } else if (0 != (status & FileInformation.STATUS_VERSIONED_UPTODATE)) {
224             return uptodateFormat.format(new Object JavaDoc [] { name, textAnnotation });
225         } else if (0 != (status & FileInformation.STATUS_NOTVERSIONED_EXCLUDED)) {
226             return excludedFormat.format(new Object JavaDoc [] { name, textAnnotation });
227         } else if (0 != (status & FileInformation.STATUS_NOTVERSIONED_NOTMANAGED)) {
228             return name;
229         } else if (status == FileInformation.STATUS_UNKNOWN) {
230             return name;
231         } else {
232             throw new IllegalArgumentException JavaDoc("Uncomparable status: " + status); // NOI18N
233
}
234     }
235
236     /**
237      * Applies custom format.
238      */

239     private String JavaDoc formatAnnotation(FileInformation info, File JavaDoc file) {
240         String JavaDoc statusString = ""; // NOI18N
241
int status = info.getStatus();
242         if (status != FileInformation.STATUS_VERSIONED_UPTODATE) {
243             statusString = info.getShortStatusText();
244         }
245
246         String JavaDoc revisionString = ""; // NOI18N
247
String JavaDoc binaryString = ""; // NOI18N
248

249                 
250         ISVNStatus snvStatus = info.getEntry(file);
251         if (snvStatus != null) {
252             revisionString = snvStatus.getRevision().toString();
253             if(mimeTypeFlag) {
254                 binaryString = getMimeType(file);
255             }
256         }
257
258         String JavaDoc stickyString = SvnUtils.getCopy(file);
259         if (stickyString == null) {
260             stickyString = ""; // NOI18N
261
}
262
263         Object JavaDoc[] arguments = new Object JavaDoc[] {
264             revisionString,
265             statusString,
266             stickyString,
267             binaryString
268         };
269                 
270         String JavaDoc annotation = format.format(arguments, new StringBuffer JavaDoc(), null).toString().trim();
271         if(annotation.equals(emptyFormat)) {
272             return "";
273         } else {
274             return " " + annotation;
275         }
276     }
277
278     private String JavaDoc getMimeType(File JavaDoc file) {
279         try {
280             SvnClient client = Subversion.getInstance().getClient(false);
281             ISVNProperty prop = client.propertyGet(file, ISVNProperty.MIME_TYPE);
282             if(prop != null) {
283                 String JavaDoc mime = prop.getValue();
284                 return mime != null ? mime : "";
285             }
286         } catch (SVNClientException ex) {
287             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); // should not hapen
288
return "";
289         }
290         return "";
291     }
292     
293     private String JavaDoc annotateFolderNameHtml(String JavaDoc name, FileInformation info, File JavaDoc file) {
294         name = htmlEncode(name);
295         int status = info.getStatus();
296         String JavaDoc textAnnotation;
297         String JavaDoc textAnnotationFormat = SvnModuleConfig.getDefault().getPreferences().get(SvnModuleConfig.PROP_TEXT_ANNOTATIONS_FORMAT, null);
298         if (textAnnotationFormat != null && file != null && (status & FileInformation.STATUS_MANAGED) != 0) {
299
300             if (format != null) {
301                 textAnnotation = formatAnnotation(info, file);
302             } else {
303                 String JavaDoc sticky;
304                 ISVNStatus lstatus = info.getEntry(file);
305                 if (lstatus != null && lstatus.getUrl() != null) {
306                     sticky = SvnUtils.getCopy(lstatus.getUrl());
307                 } else {
308                     // slower
309
sticky = SvnUtils.getCopy(file);
310                 }
311
312                 if (status == FileInformation.STATUS_VERSIONED_UPTODATE && sticky == null) {
313                     textAnnotation = ""; // NOI18N
314
} else if (status == FileInformation.STATUS_VERSIONED_UPTODATE) {
315                     textAnnotation = " [" + sticky + "]"; // NOI18N
316
} else if (sticky == null) {
317                     String JavaDoc statusText = info.getShortStatusText();
318                     if(!statusText.equals("")) { // NOI18N
319
textAnnotation = " [" + info.getShortStatusText() + "]"; // NOI18N
320
} else {
321                         textAnnotation = ""; // NOI18N
322
}
323                 } else {
324                     textAnnotation = " [" + info.getShortStatusText() + "; " + sticky + "]"; // NOI18N
325
}
326             }
327         } else {
328             textAnnotation = ""; // NOI18N
329
}
330         if (textAnnotation.length() > 0) {
331             textAnnotation = NbBundle.getMessage(Annotator.class, "textAnnotation", textAnnotation); // NOI18N
332
}
333         
334         if (status == FileInformation.STATUS_UNKNOWN) {
335             return name;
336         } else if (match(status, FileInformation.STATUS_VERSIONED_REMOVEDLOCALLY)) {
337             return name;
338         } else if (match(status, FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY)) {
339             return uptodateFormat.format(new Object JavaDoc [] { name, textAnnotation });
340         } else if (match(status, FileInformation.STATUS_VERSIONED_ADDEDLOCALLY)) {
341             return uptodateFormat.format(new Object JavaDoc [] { name, textAnnotation });
342         } else if (match(status, FileInformation.STATUS_VERSIONED_UPTODATE)) {
343             return uptodateFormat.format(new Object JavaDoc [] { name, textAnnotation });
344         } else if (match(status, FileInformation.STATUS_NOTVERSIONED_EXCLUDED)) {
345             return excludedFormat.format(new Object JavaDoc [] { name, textAnnotation });
346         } else if (match(status, FileInformation.STATUS_VERSIONED_DELETEDLOCALLY)) {
347             return name;
348         } else if (match(status, FileInformation.STATUS_VERSIONED_NEWINREPOSITORY)) {
349             return name;
350         } else if (match(status, FileInformation.STATUS_VERSIONED_MODIFIEDINREPOSITORY)) {
351             return name;
352         } else if (match(status, FileInformation.STATUS_VERSIONED_REMOVEDINREPOSITORY)) {
353             return name;
354         } else if (match(status, FileInformation.STATUS_NOTVERSIONED_NOTMANAGED)) {
355             return name;
356         } else if (match(status, FileInformation.STATUS_VERSIONED_MERGE)) {
357             return name;
358         } else if (match(status, FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY)) {
359             return name;
360         } else if (match(status, FileInformation.STATUS_VERSIONED_CONFLICT)) {
361             return name;
362         } else {
363             throw new IllegalArgumentException JavaDoc("Unknown status: " + status); // NOI18N
364
}
365     }
366
367     private static boolean match(int status, int mask) {
368         return (status & mask) != 0;
369     }
370
371     private String JavaDoc htmlEncode(String JavaDoc name) {
372         if (name.indexOf('<') == -1) return name;
373         return lessThan.matcher(name).replaceAll("&lt;"); // NOI18N
374
}
375
376     public String JavaDoc annotateNameHtml(File JavaDoc file, FileInformation info) {
377         return annotateNameHtml(file.getName(), info, file);
378     }
379     
380     public String JavaDoc annotateNameHtml(String JavaDoc name, VCSContext context, int includeStatus) {
381         FileInformation mostImportantInfo = null;
382         File JavaDoc mostImportantFile = null;
383         boolean folderAnnotation = false;
384         
385         for (File JavaDoc file : context.getRootFiles()) {
386             FileInformation info = cache.getStatus(file);
387             int status = info.getStatus();
388             if ((status & includeStatus) == 0) continue;
389             
390             if (isMoreImportant(info, mostImportantInfo)) {
391                 mostImportantInfo = info;
392                 mostImportantFile = file;
393                 folderAnnotation = file.isDirectory();
394             }
395         }
396
397         if (folderAnnotation == false && context.getRootFiles().size() > 1) {
398             folderAnnotation = !Utils.shareCommonDataObject(context.getRootFiles().toArray(new File JavaDoc[context.getRootFiles().size()]));
399         }
400
401         if (mostImportantInfo == null) return null;
402         return folderAnnotation ?
403                 annotateFolderNameHtml(name, mostImportantInfo, mostImportantFile) :
404                 annotateNameHtml(name, mostImportantInfo, mostImportantFile);
405     }
406     
407     private boolean isMoreImportant(FileInformation a, FileInformation b) {
408         if (b == null) return true;
409         if (a == null) return false;
410         return SvnUtils.getComparableStatus(a.getStatus()) < SvnUtils.getComparableStatus(b.getStatus());
411     }
412
413     String JavaDoc annotateName(String JavaDoc name, Set files) {
414         return null;
415     }
416
417     /**
418      * Returns array of versioning actions that may be used to construct a popup menu. These actions
419      * will act on the supplied context.
420      *
421      * @param ctx context similar to {@link org.openide.util.ContextAwareAction#createContextAwareInstance(org.openide.util.Lookup)}
422      * @param destination
423      * @return Action[] array of versioning actions that may be used to construct a popup menu. These actions
424      * will act on currently activated nodes.
425      */

426     public static Action [] getActions(VCSContext ctx, VCSAnnotator.ActionDestination destination) {
427         ResourceBundle loc = NbBundle.getBundle(Annotator.class);
428         Node [] nodes = ctx.getNodes();
429         File JavaDoc [] files = ctx.getRootFiles().toArray(new File JavaDoc[ctx.getRootFiles().size()]);
430         Lookup context = Lookups.fixed(ctx.getNodes());
431         boolean noneVersioned = isNothingVersioned(files);
432         boolean onlyFolders = onlyFolders(files);
433         boolean onlyProjects = onlyProjects(ctx.getNodes());
434         
435         List JavaDoc<Action> actions = new ArrayList<Action>(20);
436         if (destination == VCSAnnotator.ActionDestination.MainMenu) {
437             actions.add(SystemAction.get(CheckoutAction.class));
438             actions.add(SystemAction.get(ImportAction.class));
439             actions.add(new RelocateAction(loc.getString("CTL_MenuItem_Relocate"), ctx));
440             actions.add(null);
441             actions.add(SystemAction.get(UpdateWithDependenciesAction.class));
442             actions.add(null);
443             actions.add(SystemAction.get(StatusAction.class));
444             actions.add(SystemAction.get(DiffAction.class));
445             actions.add(SystemAction.get(UpdateAction.class));
446             actions.add(SystemAction.get(CommitAction.class));
447             actions.add(null);
448             actions.add(SystemAction.get(ExportDiffAction.class));
449             actions.add(null);
450             actions.add(SystemAction.get(CreateCopyAction.class));
451             actions.add(SystemAction.get(SwitchToAction.class));
452             actions.add(SystemAction.get(MergeAction.class));
453             actions.add(null);
454             actions.add(SystemAction.get(BlameAction.class));
455             actions.add(SystemAction.get(SearchHistoryAction.class));
456             actions.add(null);
457             actions.add(SystemAction.get(RevertModificationsAction.class));
458             actions.add(SystemAction.get(ResolveConflictsAction.class));
459             actions.add(SystemAction.get(IgnoreAction.class));
460             actions.add(null);
461             actions.add(SystemAction.get(SvnPropertiesAction.class));
462         } else {
463             if (noneVersioned) {
464                 actions.add(SystemActionBridge.createAction(SystemAction.get(ImportAction.class).createContextAwareInstance(context), loc.getString("CTL_PopupMenuItem_Import"), context));
465             } else {
466                 actions.add(SystemActionBridge.createAction(SystemAction.get(StatusAction.class), loc.getString("CTL_PopupMenuItem_Status"), context));
467                 actions.add(SystemActionBridge.createAction(SystemAction.get(DiffAction.class), loc.getString("CTL_PopupMenuItem_Diff"), context));
468                 actions.add(SystemActionBridge.createAction(SystemAction.get(UpdateAction.class), loc.getString("CTL_PopupMenuItem_Update"), context));
469                 if (onlyProjects) {
470                     actions.add(new SystemActionBridge(SystemAction.get(UpdateWithDependenciesAction.class), loc.getString("CTL_PopupMenuItem_UpdateWithDeps")));
471                 }
472                 actions.add(SystemActionBridge.createAction(SystemAction.get(CommitAction.class), loc.getString("CTL_PopupMenuItem_Commit"), context));
473                 actions.add(null);
474                 actions.add(SystemActionBridge.createAction(SystemAction.get(CreateCopyAction.class), loc.getString("CTL_PopupMenuItem_Copy"), context));
475                 actions.add(SystemActionBridge.createAction(SystemAction.get(SwitchToAction.class), loc.getString("CTL_PopupMenuItem_Switch"), context));
476                 actions.add(SystemActionBridge.createAction(SystemAction.get(MergeAction.class), loc.getString("CTL_PopupMenuItem_Merge"), context));
477                 actions.add(null);
478                 if (!onlyFolders) {
479                     actions.add(SystemActionBridge.createAction(SystemAction.get(BlameAction.class),
480                                                                 ((BlameAction)SystemAction.get(BlameAction.class)).visible(nodes) ?
481                                                                         loc.getString("CTL_PopupMenuItem_HideAnnotations") :
482                                                                         loc.getString("CTL_PopupMenuItem_ShowAnnotations"), context));
483                 }
484                 actions.add(SystemActionBridge.createAction(SystemAction.get(SearchHistoryAction.class), loc.getString("CTL_PopupMenuItem_SearchHistory"), context));
485                 actions.add(null);
486                 actions.add(SystemActionBridge.createAction(SystemAction.get(RevertModificationsAction.class), loc.getString("CTL_PopupMenuItem_GetClean"), context));
487                 actions.add(SystemActionBridge.createAction(SystemAction.get(ResolveConflictsAction.class), loc.getString("CTL_PopupMenuItem_ResolveConflicts"), context));
488                 if (!onlyProjects) {
489                     actions.add(SystemActionBridge.createAction(SystemAction.get(IgnoreAction.class),
490                                                                 ((IgnoreAction)SystemAction.get(IgnoreAction.class)).getActionStatus(nodes) == IgnoreAction.UNIGNORING ?
491                                                                         loc.getString("CTL_PopupMenuItem_Unignore") :
492                                                                         loc.getString("CTL_PopupMenuItem_Ignore"), context));
493                 }
494                 actions.add(null);
495                 actions.add(SystemActionBridge.createAction(
496                                 SystemAction.get(SvnPropertiesAction.class),
497                                 loc.getString("CTL_PopupMenuItem_Properties"), context));
498             }
499         }
500         return actions.toArray(new Action[actions.size()]);
501     }
502     
503     private static boolean isNothingVersioned(File JavaDoc[] files) {
504         FileStatusCache cache = Subversion.getInstance().getStatusCache();
505         for (File JavaDoc file : files) {
506             if ((cache.getStatus(file).getStatus() & FileInformation.STATUS_MANAGED) != 0) return false;
507         }
508         return true;
509     }
510     
511     private static boolean onlyProjects(Node[] nodes) {
512         if (nodes == null) return false;
513         for (Node node : nodes) {
514             if (node.getLookup().lookup(Project.class) == null) return false;
515         }
516         return true;
517     }
518     
519     private static boolean onlyFolders(File JavaDoc[] files) {
520         FileStatusCache cache = Subversion.getInstance().getStatusCache();
521         for (int i = 0; i < files.length; i++) {
522             if (files[i].isFile()) return false;
523             if (!files[i].exists() && !cache.getStatus(files[i]).isDirectory()) return false;
524         }
525         return true;
526     }
527
528     private static MessageFormat JavaDoc getFormat(String JavaDoc key) {
529         String JavaDoc format = NbBundle.getMessage(Annotator.class, key);
530         return new MessageFormat JavaDoc(format);
531     }
532
533     private static final int STATUS_BADGEABLE = FileInformation.STATUS_VERSIONED_UPTODATE | FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY | FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY;
534     
535     public Image annotateIcon(Image icon, VCSContext context) {
536         boolean folderAnnotation = false;
537         for (File JavaDoc file : context.getRootFiles()) {
538             if (file.isDirectory()) {
539                 folderAnnotation = true;
540                 break;
541             }
542         }
543         
544         if (folderAnnotation == false && context.getRootFiles().size() > 1) {
545             folderAnnotation = !Utils.shareCommonDataObject(context.getRootFiles().toArray(new File JavaDoc[context.getRootFiles().size()]));
546         }
547
548         if (folderAnnotation == false) {
549             return null;
550         }
551
552         FileStatusCache cache = Subversion.getInstance().getStatusCache();
553         boolean isVersioned = false;
554         for (Iterator i = context.getRootFiles().iterator(); i.hasNext();) {
555             File JavaDoc file = (File JavaDoc) i.next();
556             if ((cache.getStatus(file).getStatus() & STATUS_BADGEABLE) != 0) {
557                 isVersioned = true;
558                 break;
559             }
560         }
561         if (!isVersioned) return null;
562         
563         SvnModuleConfig config = SvnModuleConfig.getDefault();
564         boolean allExcluded = true;
565         boolean modified = false;
566
567         Map map = cache.getAllModifiedFiles();
568         Map<File JavaDoc, FileInformation> modifiedFiles = new HashMap<File JavaDoc, FileInformation>();
569         for (Iterator i = map.keySet().iterator(); i.hasNext();) {
570             File JavaDoc file = (File JavaDoc) i.next();
571             FileInformation info = (FileInformation) map.get(file);
572             if ((info.getStatus() & FileInformation.STATUS_LOCAL_CHANGE) != 0) modifiedFiles.put(file, info);
573         }
574
575         for (Iterator i = context.getRootFiles().iterator(); i.hasNext();) {
576             File JavaDoc file = (File JavaDoc) i.next();
577             if (file instanceof FlatFolder) {
578                 for (Iterator j = modifiedFiles.keySet().iterator(); j.hasNext();) {
579                     File JavaDoc mf = (File JavaDoc) j.next();
580                     if (mf.getParentFile().equals(file)) {
581                         FileInformation info = (FileInformation) modifiedFiles.get(mf);
582                         if (info.isDirectory()) continue;
583                         int status = info.getStatus();
584                         if (status == FileInformation.STATUS_VERSIONED_CONFLICT) {
585                             Image badge = Utilities.loadImage("org/netbeans/modules/versioning/system/cvss/resources/icons/conflicts-badge.png", true); // NOI18N
586
return Utilities.mergeImages(icon, badge, 16, 9);
587                         }
588                         modified = true;
589                         allExcluded &= config.isExcludedFromCommit(mf.getAbsolutePath());
590                     }
591                 }
592             } else {
593                 for (Iterator j = modifiedFiles.keySet().iterator(); j.hasNext();) {
594                     File JavaDoc mf = (File JavaDoc) j.next();
595                     if (Utils.isParentOrEqual(file, mf)) {
596                         FileInformation info = (FileInformation) modifiedFiles.get(mf);
597                         int status = info.getStatus();
598                         if ((status == FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY || status == FileInformation.STATUS_VERSIONED_ADDEDLOCALLY) && file.equals(mf)) {
599                             continue;
600                         }
601                         if (status == FileInformation.STATUS_VERSIONED_CONFLICT) {
602                             Image badge = Utilities.loadImage("org/netbeans/modules/versioning/system/cvss/resources/icons/conflicts-badge.png", true); // NOI18N
603
return Utilities.mergeImages(icon, badge, 16, 9);
604                         }
605                         modified = true;
606                         allExcluded &= config.isExcludedFromCommit(mf.getAbsolutePath());
607                     }
608                 }
609             }
610         }
611
612         if (modified && !allExcluded) {
613             Image badge = Utilities.loadImage("org/netbeans/modules/versioning/system/cvss/resources/icons/modified-badge.png", true); // NOI18N
614
return Utilities.mergeImages(icon, badge, 16, 9);
615         } else {
616             return null;
617         }
618     }
619
620 }
621
Popular Tags