KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > ui > repo > RepositoryManager


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Sebastian Davids <sdavids@gmx.de> - bug 74959
11  * Maik Schreiber - bug 102461
12  * William Mitsuda (wmitsuda@gmail.com) - Bug 153879 [Wizards] configurable size of cvs commit comment history
13  *******************************************************************************/

14 package org.eclipse.team.internal.ccvs.ui.repo;
15
16
17 import java.io.*;
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.util.*;
20
21 import javax.xml.parsers.*;
22
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.runtime.*;
26 import org.eclipse.jface.dialogs.IDialogConstants;
27 import org.eclipse.jface.operation.IRunnableWithProgress;
28 import org.eclipse.jface.preference.IPreferenceStore;
29 import org.eclipse.jface.util.IPropertyChangeListener;
30 import org.eclipse.jface.util.PropertyChangeEvent;
31 import org.eclipse.jface.window.Window;
32 import org.eclipse.osgi.util.NLS;
33 import org.eclipse.swt.widgets.Shell;
34 import org.eclipse.team.core.TeamException;
35 import org.eclipse.team.internal.ccvs.core.*;
36 import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
37 import org.eclipse.team.internal.ccvs.core.util.KnownRepositories;
38 import org.eclipse.team.internal.ccvs.ui.*;
39 import org.eclipse.team.internal.ccvs.ui.Policy;
40 import org.eclipse.ui.IWorkingSet;
41 import org.xml.sax.InputSource JavaDoc;
42 import org.xml.sax.SAXException JavaDoc;
43
44 /**
45  * This class is repsible for maintaining the UI's list of known repositories,
46  * and a list of known tags within each of those repositories.
47  *
48  * It also provides a number of useful methods for assisting in repository operations.
49  */

50 public class RepositoryManager {
51     // old state file
52
private static final String JavaDoc STATE_FILE = ".repositoryManagerState"; //$NON-NLS-1$
53
private static final int STATE_FILE_VERSION_1 = -1;
54     // new state file
55
private static final String JavaDoc REPOSITORIES_VIEW_FILE = "repositoriesView.xml"; //$NON-NLS-1$
56
private static final String JavaDoc COMMENT_HIST_FILE = "commitCommentHistory.xml"; //$NON-NLS-1$
57
private static final String JavaDoc COMMENT_TEMPLATES_FILE = "commentTemplates.xml"; //$NON-NLS-1$
58
static final String JavaDoc ELEMENT_COMMIT_COMMENT = "CommitComment"; //$NON-NLS-1$
59
static final String JavaDoc ELEMENT_COMMIT_HISTORY = "CommitComments"; //$NON-NLS-1$
60
static final String JavaDoc ELEMENT_COMMENT_TEMPLATES = "CommitCommentTemplates"; //$NON-NLS-1$
61

62     private Map repositoryRoots = new HashMap();
63     
64     List listeners = new ArrayList();
65
66     // The previously remembered comment
67
static String JavaDoc[] previousComments = new String JavaDoc[0];
68     static String JavaDoc[] commentTemplates = new String JavaDoc[0];
69     
70     public static boolean notifyRepoView = true;
71     
72     // Cache of changed repository roots
73
private int notificationLevel = 0;
74     private Map changedRepositories = new HashMap();
75     
76     public static final int DEFAULT_MAX_COMMENTS = 10;
77     
78     private int maxComments = DEFAULT_MAX_COMMENTS;
79     
80     public void setMaxComments(int maxComments) {
81         if (maxComments > 0) {
82             this.maxComments = maxComments;
83             if (maxComments < previousComments.length) {
84                 String JavaDoc[] newComments = new String JavaDoc[maxComments];
85                 System.arraycopy(previousComments, 0, newComments, 0, maxComments);
86                 previousComments = newComments;
87             }
88         }
89     }
90     
91     /**
92      * Answer an array of all known remote roots.
93      */

94     public ICVSRepositoryLocation[] getKnownRepositoryLocations() {
95         return KnownRepositories.getInstance().getRepositories();
96     }
97     
98     /**
99      * Method getRepositoryRoots.
100      * @param iCVSRepositoryLocations
101      * @return RepositoryRoot[]
102      */

103     private RepositoryRoot[] getRepositoryRoots(ICVSRepositoryLocation[] locations) {
104         List roots = new ArrayList();
105         for (int i = 0; i < locations.length; i++) {
106             ICVSRepositoryLocation location = locations[i];
107             RepositoryRoot root = getRepositoryRootFor(location);
108             if (root != null)
109                 roots.add(root);
110         }
111         return (RepositoryRoot[]) roots.toArray(new RepositoryRoot[roots.size()]);
112     }
113     
114     public RepositoryRoot[] getKnownRepositoryRoots() {
115         return getRepositoryRoots(getKnownRepositoryLocations());
116     }
117     
118     /**
119      * Get the list of known branch tags for a given remote root.
120      */

121     public CVSTag[] getKnownTags(ICVSFolder project, int tagType) {
122         try {
123             CVSTag[] tags = getKnownTags(project);
124             Set result = new HashSet();
125             for (int i = 0; i < tags.length; i++) {
126                 CVSTag tag = tags[i];
127                 if (tag.getType() == tagType)
128                     result.add(tag);
129             }
130
131             return (CVSTag[])result.toArray(new CVSTag[result.size()]);
132         } catch(CVSException e) {
133             CVSUIPlugin.log(e);
134             return new CVSTag[0];
135         }
136     }
137     
138     /**
139      * Get the list of known version tags for a given project.
140      */

141     public CVSTag[] getKnownTags(ICVSRepositoryLocation location, int tagType) {
142         Set result = new HashSet();
143         RepositoryRoot root = (RepositoryRoot)repositoryRoots.get(location.getLocation(false));
144         if (root != null) {
145             String JavaDoc[] paths = root.getKnownRemotePaths();
146             for (int i = 0; i < paths.length; i++) {
147                 String JavaDoc path = paths[i];
148                 CVSTag[] tags = root.getAllKnownTags(path);
149                 for (int j = 0; j < tags.length; j++) {
150                     CVSTag tag = tags[j];
151                     if (tag.getType() == tagType)
152                         result.add(tag);
153                 }
154             }
155         }
156         return (CVSTag[])result.toArray(new CVSTag[0]);
157     }
158     
159     /**
160      * Method getKnownTags.
161      * @param repository
162      * @param set
163      * @param i
164      * @param monitor
165      * @return CVSTag[]
166      */

167     public CVSTag[] getKnownTags(ICVSRepositoryLocation repository, IWorkingSet set, int tagType, IProgressMonitor monitor) throws CVSException {
168         if (set == null) {
169             return getKnownTags(repository, tagType);
170         }
171         ICVSRemoteResource[] folders = getFoldersForTag(repository, CVSTag.DEFAULT, monitor);
172         folders = filterResources(set, folders);
173         Set tags = new HashSet();
174         for (int i = 0; i < folders.length; i++) {
175             ICVSRemoteFolder folder = (ICVSRemoteFolder)folders[i];
176             tags.addAll(Arrays.asList(getKnownTags(folder, tagType)));
177         }
178         return (CVSTag[]) tags.toArray(new CVSTag[tags.size()]);
179     }
180     
181     public CVSTag[] getKnownTags(ICVSFolder project) throws CVSException {
182         RepositoryRoot root = getRepositoryRootFor(project);
183         String JavaDoc remotePath = RepositoryRoot.getRemotePathFor(project);
184         return root.getAllKnownTags(remotePath);
185     }
186     
187     /*
188      * XXX I hope this methos is not needed in this form
189      */

190     public Map getKnownProjectsAndVersions(ICVSRepositoryLocation location) {
191         Map knownTags = new HashMap();
192         RepositoryRoot root = getRepositoryRootFor(location);
193         String JavaDoc[] paths = root.getKnownRemotePaths();
194         for (int i = 0; i < paths.length; i++) {
195             String JavaDoc path = paths[i];
196             Set result = new HashSet();
197             result.addAll(Arrays.asList(root.getAllKnownTags(path)));
198             knownTags.put(path, result);
199         }
200         return knownTags;
201     }
202     
203     public ICVSRemoteResource[] getFoldersForTag(ICVSRepositoryLocation location, CVSTag tag, IProgressMonitor monitor) throws CVSException {
204         monitor = Policy.monitorFor(monitor);
205         try {
206             monitor.beginTask(NLS.bind(CVSUIMessages.RepositoryManager_fetchingRemoteFolders, new String JavaDoc[] { tag.getName() }), 100);
207             if (tag.getType() == CVSTag.HEAD) {
208                 ICVSRemoteResource[] resources = location.members(tag, false, Policy.subMonitorFor(monitor, 60));
209                 RepositoryRoot root = getRepositoryRootFor(location);
210                 ICVSRemoteResource[] modules = root.getDefinedModules(tag, Policy.subMonitorFor(monitor, 40));
211                 ICVSRemoteResource[] result = new ICVSRemoteResource[resources.length + modules.length];
212                 System.arraycopy(resources, 0, result, 0, resources.length);
213                 System.arraycopy(modules, 0, result, resources.length, modules.length);
214                 return result;
215             }
216             if (tag.getType() == CVSTag.DATE) {
217                 ICVSRemoteResource[] resources = location.members(tag, false, Policy.subMonitorFor(monitor, 60));
218                 RepositoryRoot root = getRepositoryRootFor(location);
219                 ICVSRemoteResource[] modules = root.getDefinedModules(tag, Policy.subMonitorFor(monitor, 40));
220                 ICVSRemoteResource[] result = new ICVSRemoteResource[resources.length + modules.length];
221                 System.arraycopy(resources, 0, result, 0, resources.length);
222                 System.arraycopy(modules, 0, result, resources.length, modules.length);
223                 return result;
224             }
225             Set result = new HashSet();
226             // Get the tags for the location
227
RepositoryRoot root = getRepositoryRootFor(location);
228             String JavaDoc[] paths = root.getKnownRemotePaths();
229             for (int i = 0; i < paths.length; i++) {
230                 String JavaDoc path = paths[i];
231                 List tags = Arrays.asList(root.getAllKnownTags(path));
232                 if (tags.contains(tag)) {
233                     ICVSRemoteFolder remote = root.getRemoteFolder(path, tag, Policy.subMonitorFor(monitor, 100));
234                     result.add(remote);
235                 }
236             }
237             return (ICVSRemoteResource[])result.toArray(new ICVSRemoteResource[result.size()]);
238         } finally {
239             monitor.done();
240         }
241     }
242         
243     /*
244      * Fetches tags from auto-refresh files if they exist. Then fetches tags from the user defined auto-refresh file
245      * list. The fetched tags are cached in the CVS ui plugin's tag cache.
246      */

247     public CVSTag[] refreshDefinedTags(ICVSFolder folder, boolean recurse, boolean notify, IProgressMonitor monitor) throws TeamException {
248         RepositoryRoot root = getRepositoryRootFor(folder);
249         CVSTag[] tags = root.refreshDefinedTags(folder, recurse, monitor);
250         if (tags.length > 0 && notify)
251             broadcastRepositoryChange(root);
252         return tags;
253     }
254     
255     /**
256      * A repository root has been added. Notify any listeners.
257      */

258     public void rootAdded(ICVSRepositoryLocation root) {
259         Iterator it = listeners.iterator();
260         while (it.hasNext()) {
261             IRepositoryListener listener = (IRepositoryListener)it.next();
262             listener.repositoryAdded(root);
263         }
264     }
265     
266     /**
267      * A repository root has been removed.
268      * Remove the tags defined for this root and notify any listeners
269      */

270     public void rootRemoved(ICVSRepositoryLocation root) {
271         RepositoryRoot repoRoot = (RepositoryRoot)repositoryRoots.remove(root.getLocation(false));
272         if (repoRoot != null)
273             broadcastRepositoryChange(repoRoot);
274     }
275     
276     /**
277      * Accept tags for any CVS resource. However, for the time being,
278      * the given version tags are added to the list of known tags for the
279      * remote ancestor of the resource that is a direct child of the remote root
280      */

281     public void addTags(ICVSResource resource, CVSTag[] tags) throws CVSException {
282         RepositoryRoot root = getRepositoryRootFor(resource);
283         // XXX could be a file or folder
284
String JavaDoc remotePath = RepositoryRoot.getRemotePathFor(resource);
285         root.addTags(remotePath, tags);
286         broadcastRepositoryChange(root);
287     }
288     public void addDateTag(ICVSRepositoryLocation location, CVSTag tag) {
289         if(tag == null) return;
290         RepositoryRoot root = getRepositoryRootFor(location);
291         root.addDateTag(tag);
292         broadcastRepositoryChange(root);
293     }
294     public CVSTag[] getDateTags(ICVSRepositoryLocation location) {
295         RepositoryRoot root = getRepositoryRootFor(location);
296         return root.getDateTags();
297     }
298     public void removeDateTag(ICVSRepositoryLocation location, CVSTag tag){
299         RepositoryRoot root = getRepositoryRootFor(location);
300         root.removeDateTag(tag);
301         broadcastRepositoryChange(root);
302     }
303     public void setAutoRefreshFiles(ICVSFolder project, String JavaDoc[] filePaths) throws CVSException {
304         RepositoryRoot root = getRepositoryRootFor(project);
305         String JavaDoc remotePath = RepositoryRoot.getRemotePathFor(project);
306         root.setAutoRefreshFiles(remotePath, filePaths);
307     }
308     
309     public String JavaDoc[] getAutoRefreshFiles(ICVSFolder project) throws CVSException {
310         RepositoryRoot root = getRepositoryRootFor(project);
311         String JavaDoc remotePath = RepositoryRoot.getRemotePathFor(project);
312         return root.getAutoRefreshFiles(remotePath);
313     }
314     
315     /**
316      * Remove the given tags from the list of known tags for the
317      * given remote root.
318      */

319     public void removeTags(ICVSFolder project, CVSTag[] tags) throws CVSException {
320         RepositoryRoot root = getRepositoryRootFor(project);
321         String JavaDoc remotePath = RepositoryRoot.getRemotePathFor(project);
322         root.removeTags(remotePath, tags);
323         broadcastRepositoryChange(root);
324     }
325     
326     public void startup() {
327         loadState();
328         loadCommentHistory();
329         loadCommentTemplates();
330         CVSProviderPlugin.getPlugin().addRepositoryListener(new ICVSListener() {
331             public void repositoryAdded(ICVSRepositoryLocation root) {
332                 rootAdded(root);
333             }
334             public void repositoryRemoved(ICVSRepositoryLocation root) {
335                 rootRemoved(root);
336             }
337         });
338         
339         IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore();
340         store.addPropertyChangeListener(new IPropertyChangeListener() {
341
342             public void propertyChange(PropertyChangeEvent event) {
343                 if (event.getProperty().equals(ICVSUIConstants.PREF_COMMIT_COMMENTS_MAX_HISTORY)) {
344                     Object JavaDoc newValue = event.getNewValue();
345                     if (newValue instanceof String JavaDoc) {
346                         try {
347                             setMaxComments(Integer.parseInt((String JavaDoc) newValue));
348                         } catch (NumberFormatException JavaDoc e) {
349                             // fail silently
350
}
351                     }
352                 }
353             }
354             
355         });
356         setMaxComments(store.getInt(ICVSUIConstants.PREF_COMMIT_COMMENTS_MAX_HISTORY));
357     }
358     
359     public void shutdown() throws TeamException {
360         saveState();
361         saveCommentHistory();
362         saveCommentTemplates();
363     }
364     
365     private void loadState() {
366         IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation().append(REPOSITORIES_VIEW_FILE);
367         File file = pluginStateLocation.toFile();
368         if (file.exists()) {
369             try {
370                 BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
371                 try {
372                     readState(is);
373                 } finally {
374                     is.close();
375                 }
376             } catch (IOException e) {
377                 CVSUIPlugin.log(IStatus.ERROR, CVSUIMessages.RepositoryManager_ioException, e);
378             } catch (TeamException e) {
379                 CVSUIPlugin.log(e);
380             }
381         } else {
382             IPath oldPluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation().append(STATE_FILE);
383             file = oldPluginStateLocation.toFile();
384             if (file.exists()) {
385                 try {
386                     DataInputStream dis = new DataInputStream(new FileInputStream(file));
387                     try {
388                         readOldState(dis);
389                     } finally {
390                         dis.close();
391                     }
392                     saveState();
393                     file.delete();
394                 } catch (IOException e) {
395                     CVSUIPlugin.log(IStatus.ERROR, CVSUIMessages.RepositoryManager_ioException, e);
396                 } catch (TeamException e) {
397                     CVSUIPlugin.log(e);
398                 }
399             }
400         }
401     }
402     private void loadCommentHistory() {
403         IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation().append(COMMENT_HIST_FILE);
404         File file = pluginStateLocation.toFile();
405         if (!file.exists()) return;
406         try {
407             BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
408             try {
409                 readCommentHistory(is);
410             } finally {
411                 is.close();
412             }
413         } catch (IOException e) {
414             CVSUIPlugin.log(IStatus.ERROR, CVSUIMessages.RepositoryManager_ioException, e);
415         } catch (TeamException e) {
416             CVSUIPlugin.log(e);
417         }
418     }
419     private void loadCommentTemplates() {
420         IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation().append(COMMENT_TEMPLATES_FILE);
421         File file = pluginStateLocation.toFile();
422         if (!file.exists()) return;
423         try {
424             BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
425             try {
426                 readCommentTemplates(is);
427             } finally {
428                 is.close();
429             }
430         } catch (IOException e) {
431             CVSUIPlugin.log(IStatus.ERROR, CVSUIMessages.RepositoryManager_ioException, e);
432         } catch (TeamException e) {
433             CVSUIPlugin.log(e);
434         }
435     }
436     
437     protected void saveState() throws TeamException {
438         IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation();
439         File tempFile = pluginStateLocation.append(REPOSITORIES_VIEW_FILE + ".tmp").toFile(); //$NON-NLS-1$
440
File stateFile = pluginStateLocation.append(REPOSITORIES_VIEW_FILE).toFile();
441         try {
442             XMLWriter writer = new XMLWriter(new BufferedOutputStream(new FileOutputStream(tempFile)));
443             try {
444                 writeState(writer);
445             } finally {
446                 writer.close();
447             }
448             if (stateFile.exists()) {
449                 stateFile.delete();
450             }
451             boolean renamed = tempFile.renameTo(stateFile);
452             if (!renamed) {
453                 throw new TeamException(new Status(IStatus.ERROR, CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(CVSUIMessages.RepositoryManager_rename, new String JavaDoc[] { tempFile.getAbsolutePath() }), null));
454             }
455         } catch (IOException e) {
456             throw new TeamException(new Status(IStatus.ERROR, CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(CVSUIMessages.RepositoryManager_save, new String JavaDoc[] { stateFile.getAbsolutePath() }), e));
457         }
458     }
459     private void writeState(XMLWriter writer) {
460         writer.startTag(RepositoriesViewContentHandler.REPOSITORIES_VIEW_TAG, null, true);
461         // Write the repositories
462
Collection repos = Arrays.asList(getKnownRepositoryLocations());
463         Iterator it = repos.iterator();
464         while (it.hasNext()) {
465             CVSRepositoryLocation location = (CVSRepositoryLocation)it.next();
466             RepositoryRoot root = getRepositoryRootFor(location);
467             root.writeState(writer);
468         }
469         writer.endTag(RepositoriesViewContentHandler.REPOSITORIES_VIEW_TAG);
470     }
471     
472     private void readState(InputStream stream) throws IOException, TeamException {
473         try {
474             SAXParserFactory factory = SAXParserFactory.newInstance();
475             SAXParser parser = factory.newSAXParser();
476             parser.parse(new InputSource JavaDoc(stream), new RepositoriesViewContentHandler(this));
477         } catch (SAXException JavaDoc ex) {
478             IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(CVSUIMessages.RepositoryManager_parsingProblem, new String JavaDoc[] { REPOSITORIES_VIEW_FILE }), ex);
479             throw new CVSException(status);
480         } catch (ParserConfigurationException ex) {
481             IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(CVSUIMessages.RepositoryManager_parsingProblem, new String JavaDoc[] { REPOSITORIES_VIEW_FILE }), ex);
482             throw new CVSException(status);
483         }
484     }
485     
486     private void readCommentHistory(InputStream stream) throws IOException, TeamException {
487         try {
488             SAXParserFactory factory = SAXParserFactory.newInstance();
489             SAXParser parser = factory.newSAXParser();
490             parser.parse(new InputSource JavaDoc(stream), new CommentHistoryContentHandler());
491         } catch (SAXException JavaDoc ex) {
492             IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(CVSUIMessages.RepositoryManager_parsingProblem, new String JavaDoc[] { COMMENT_HIST_FILE }), ex);
493             throw new CVSException(status);
494         } catch (ParserConfigurationException ex) {
495             IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(CVSUIMessages.RepositoryManager_parsingProblem, new String JavaDoc[] { COMMENT_HIST_FILE }), ex);
496             throw new CVSException(status);
497         }
498     }
499     
500     private void readOldState(DataInputStream dis) throws IOException, TeamException {
501         int repoSize = dis.readInt();
502         boolean version1 = false;
503         if (repoSize == STATE_FILE_VERSION_1) {
504             version1 = true;
505             repoSize = dis.readInt();
506         }
507         for (int i = 0; i < repoSize; i++) {
508             ICVSRepositoryLocation root = KnownRepositories.getInstance().getRepository(dis.readUTF());
509             RepositoryRoot repoRoot = getRepositoryRootFor(root);
510             
511             // read branch tags associated with this root
512
int tagsSize = dis.readInt();
513             CVSTag[] branchTags = new CVSTag[tagsSize];
514             for (int j = 0; j < tagsSize; j++) {
515                 String JavaDoc tagName = dis.readUTF();
516                 int tagType = dis.readInt();
517                 branchTags[j] = new CVSTag(tagName, tagType);
518             }
519             // Ignore the branch tags since they are handled differently now
520
// addBranchTags(root, branchTags);
521

522             // read the number of projects for this root that have version tags
523
int projSize = dis.readInt();
524             if (projSize > 0) {
525                 for (int j = 0; j < projSize; j++) {
526                     String JavaDoc name = dis.readUTF();
527                     Set tagSet = new HashSet();
528                     int numTags = dis.readInt();
529                     for (int k = 0; k < numTags; k++) {
530                         tagSet.add(new CVSTag(dis.readUTF(), CVSTag.VERSION));
531                     }
532                     CVSTag[] tags = (CVSTag[]) tagSet.toArray(new CVSTag[tagSet.size()]);
533                     repoRoot.addTags(name, tags);
534                 }
535             }
536             // read the auto refresh filenames for this project
537
if (version1) {
538                 try {
539                     projSize = dis.readInt();
540                     if (projSize > 0) {
541                         for (int j = 0; j < projSize; j++) {
542                             String JavaDoc name = dis.readUTF();
543                             Set filenames = new HashSet();
544                             int numFilenames = dis.readInt();
545                             for (int k = 0; k < numFilenames; k++) {
546                                 filenames.add(name + "/" + dis.readUTF()); //$NON-NLS-1$
547
}
548                             repoRoot.setAutoRefreshFiles(name, (String JavaDoc[]) filenames.toArray(new String JavaDoc[filenames.size()]));
549                         }
550                     }
551                 } catch (EOFException e) {
552                     // auto refresh files are not persisted, continue and save them next time.
553
}
554             }
555             broadcastRepositoryChange(repoRoot);
556         }
557     }
558     
559     protected void saveCommentHistory() throws TeamException {
560         IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation();
561         File tempFile = pluginStateLocation.append(COMMENT_HIST_FILE + ".tmp").toFile(); //$NON-NLS-1$
562
File histFile = pluginStateLocation.append(COMMENT_HIST_FILE).toFile();
563         try {
564                  XMLWriter writer = new XMLWriter(new BufferedOutputStream(new FileOutputStream(tempFile)));
565                  try {
566                          writeCommentHistory(writer);
567                  } finally {
568                          writer.close();
569                  }
570                  if (histFile.exists()) {
571                          histFile.delete();
572                  }
573                  boolean renamed = tempFile.renameTo(histFile);
574                  if (!renamed) {
575                          throw new TeamException(new Status(IStatus.ERROR, CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(CVSUIMessages.RepositoryManager_rename, new String JavaDoc[] { tempFile.getAbsolutePath() }), null));
576                  }
577          } catch (IOException e) {
578                  throw new TeamException(new Status(IStatus.ERROR, CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(CVSUIMessages.RepositoryManager_save, new String JavaDoc[] { histFile.getAbsolutePath() }), e));
579          }
580     }
581     private void writeCommentHistory(XMLWriter writer) {
582         writer.startTag(ELEMENT_COMMIT_HISTORY, null, false);
583         for (int i = 0; i < previousComments.length && i < maxComments; i++)
584             writer.printSimpleTag(ELEMENT_COMMIT_COMMENT, previousComments[i]);
585         writer.endTag(ELEMENT_COMMIT_HISTORY);
586     }
587          
588     public void addRepositoryListener(IRepositoryListener listener) {
589         listeners.add(listener);
590     }
591     
592     public void removeRepositoryListener(IRepositoryListener listener) {
593         listeners.remove(listener);
594     }
595     
596     /**
597      * Return the entered comment or null if canceled.
598      * @param proposedComment
599      */

600     public String JavaDoc promptForComment(final Shell shell, IResource[] resourcesToCommit, String JavaDoc proposedComment) {
601         final int[] result = new int[1];
602         final ReleaseCommentDialog dialog = new ReleaseCommentDialog(shell, resourcesToCommit, proposedComment, IResource.DEPTH_INFINITE);
603         shell.getDisplay().syncExec(new Runnable JavaDoc() {
604             public void run() {
605                 result[0] = dialog.open();
606                 if (result[0] != Window.OK) return;
607             }
608         });
609         if (result[0] != Window.OK) return null;
610         return dialog.getComment();
611     }
612     
613     /**
614      * Prompt to add all or some of the provided resources to version control.
615      * The value null is returned if the dialog is cancelled.
616      *
617      * @param shell
618      * @param unadded
619      * @return IResource[]
620      */

621     public IResource[] promptForResourcesToBeAdded(Shell shell, IResource[] unadded) {
622         if (unadded == null) return new IResource[0];
623         if (unadded.length == 0) return unadded;
624         final IResource[][] result = new IResource[1][0];
625         result[0] = null;
626         final AddToVersionControlDialog dialog = new AddToVersionControlDialog(shell, unadded);
627         shell.getDisplay().syncExec(new Runnable JavaDoc() {
628             public void run() {
629                 int code = dialog.open();
630                 if (code == IDialogConstants.YES_ID) {
631                     result[0] = dialog.getResourcesToAdd();
632                 } else if(code == IDialogConstants.NO_ID) {
633                     // allow the commit to continue.
634
result[0] = new IResource[0];
635                 }
636             }
637         });
638         return result[0];
639     }
640     
641     public ICVSRepositoryLocation getRepositoryLocationFor(ICVSResource resource) {
642         try {
643             return internalGetRepositoryLocationFor(resource);
644         } catch (CVSException e) {
645             CVSUIPlugin.log(e);
646             return null;
647         }
648     }
649
650     private ICVSRepositoryLocation internalGetRepositoryLocationFor(ICVSResource resource) throws CVSException {
651         ICVSFolder folder;
652         if (resource.isFolder()) {
653             folder = (ICVSFolder)resource;
654         } else {
655             folder = resource.getParent();
656         }
657         if (folder.isCVSFolder()) {
658             ICVSRepositoryLocation location = KnownRepositories.getInstance().getRepository(folder.getFolderSyncInfo().getRoot());
659             return location;
660         }
661         // XXX This is asking for trouble
662
return null;
663     }
664         
665     private RepositoryRoot getRepositoryRootFor(ICVSResource resource) throws CVSException {
666         ICVSRepositoryLocation location = internalGetRepositoryLocationFor(resource);
667         if (location == null) return null;
668         return getRepositoryRootFor(location);
669     }
670     
671     public RepositoryRoot getRepositoryRootFor(ICVSRepositoryLocation location) {
672         RepositoryRoot root = (RepositoryRoot)repositoryRoots.get(location.getLocation(false));
673         if (root == null) {
674             root = new RepositoryRoot(location);
675             add(root);
676         }
677         return root;
678     }
679     
680     /**
681      * Add the given repository root to the receiver. The provided instance of RepositoryRoot
682      * is used to provide extra information about the repository location
683      *
684      * @param currentRepositoryRoot
685      */

686     public void add(RepositoryRoot root) {
687         repositoryRoots.put(root.getRoot().getLocation(false), root);
688         broadcastRepositoryChange(root);
689     }
690     
691     private void broadcastRepositoryChange(RepositoryRoot root) {
692         if (notificationLevel == 0) {
693             broadcastRepositoriesChanged(new ICVSRepositoryLocation[] {root.getRoot()});
694         } else {
695             changedRepositories.put(root.getRoot().getLocation(false), root.getRoot());
696         }
697     }
698     
699     private void broadcastRepositoriesChanged(ICVSRepositoryLocation[] roots) {
700         if (roots.length == 0) return;
701         Iterator it = listeners.iterator();
702         while (it.hasNext()) {
703             IRepositoryListener listener = (IRepositoryListener)it.next();
704             listener.repositoriesChanged(roots);
705         }
706     }
707     
708     /**
709      * Run the given runnable, waiting until the end to perform a refresh
710      *
711      * @param runnable
712      * @param monitor
713      */

714     public void run(IRunnableWithProgress runnable, IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
715         try {
716             notificationLevel++;
717             runnable.run(monitor);
718         } finally {
719             notificationLevel = Math.max(0, notificationLevel - 1);
720             if (notificationLevel == 0) {
721                 try {
722                     Collection roots = changedRepositories.values();
723                     broadcastRepositoriesChanged((ICVSRepositoryLocation[]) roots.toArray(new ICVSRepositoryLocation[roots.size()]));
724                 } finally {
725                     changedRepositories.clear();
726                 }
727             }
728         }
729     }
730     
731     /**
732      * Method isDisplayingProjectVersions.
733      * @param repository
734      * @return boolean
735      */

736     public boolean isDisplayingProjectVersions(ICVSRepositoryLocation repository) {
737         return true;
738     }
739     
740     /**
741      * Method filterResources filters the given resources using the given
742      * working set.
743      *
744      * @param current
745      * @param resources
746      * @return ICVSRemoteResource[]
747      */

748     public ICVSRemoteResource[] filterResources(IWorkingSet workingSet, ICVSRemoteResource[] resources) {
749         if (workingSet == null) return resources;
750         // get the projects associated with the working set
751
IAdaptable[] adaptables = workingSet.getElements();
752         Set projects = new HashSet();
753         for (int i = 0; i < adaptables.length; i++) {
754             IAdaptable adaptable = adaptables[i];
755             Object JavaDoc adapted = adaptable.getAdapter(IResource.class);
756             if (adapted != null) {
757                 // Can this code be generalized?
758
IProject project = ((IResource)adapted).getProject();
759                 projects.add(project);
760             }
761         }
762         List result = new ArrayList();
763         for (int i = 0; i < resources.length; i++) {
764             ICVSRemoteResource resource = resources[i];
765             for (Iterator iter = projects.iterator(); iter.hasNext();) {
766                 IProject project = (IProject) iter.next();
767                 if (project.getName().equals(resource.getName())) {
768                     result.add(resource);
769                     break;
770                 }
771             }
772         }
773         return (ICVSRemoteResource[]) result.toArray(new ICVSRemoteResource[result.size()]);
774     }
775     
776     /**
777      * Method setLabel.
778      * @param location
779      * @param label
780      */

781     public void setLabel(CVSRepositoryLocation location, String JavaDoc label) {
782         RepositoryRoot root = getRepositoryRootFor(location);
783         String JavaDoc oldLabel = root.getName();
784         if (oldLabel == null) {
785             if (label == null) return;
786             root.setName(label);
787         } else if (label == null) {
788             root.setName(label);
789         } else if (label.equals(oldLabel)) {
790             return;
791         } else {
792             root.setName(label);
793         }
794         broadcastRepositoryChange(root);
795     }
796     
797     /**
798      * Replace the old repository location with the new one assuming that they
799      * are the same location with different authentication informations
800      * @param location
801      * @param newLocation
802      */

803     public void replaceRepositoryLocation(
804             final ICVSRepositoryLocation oldLocation,
805             final CVSRepositoryLocation newLocation) {
806         
807         try {
808             run(new IRunnableWithProgress() {
809                 public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
810                     RepositoryRoot root = getRepositoryRootFor(oldLocation);
811                     // Disposing of the old location will result in the deletion of the
812
// cached root through a listener callback
813
KnownRepositories.getInstance().disposeRepository(oldLocation);
814                     
815                     // Get the new location from the CVS plugin to ensure we use the
816
// instance that will be returned by future calls to getRepository()
817
boolean isNew = !KnownRepositories.getInstance().isKnownRepository(newLocation.getLocation());
818                     root.setRepositoryLocation(
819                             KnownRepositories.getInstance().addRepository(newLocation, isNew /* broadcast */));
820                     add(root);
821                 }
822             }, Policy.monitorFor(null));
823         } catch (InvocationTargetException JavaDoc e) {
824             CVSException.wrapException(e);
825         } catch (InterruptedException JavaDoc e) {
826         }
827     }
828     
829     /**
830      * Purge any cahced information.
831      */

832     public void purgeCache() {
833         for (Iterator iter = repositoryRoots.values().iterator(); iter.hasNext();) {
834             RepositoryRoot root = (RepositoryRoot) iter.next();
835             root.clearCache();
836         }
837     }
838
839     /**
840      * Answer the list of comments that were previously used when committing.
841      * @return String[]
842      */

843     public String JavaDoc[] getPreviousComments() {
844         return previousComments;
845     }
846
847     /**
848      * Method addComment.
849      * @param string
850      */

851     public void addComment(String JavaDoc comment) {
852         // Make comment first element if it's already there
853
int index = getCommentIndex(comment);
854         if (index != -1) {
855             makeFirstElement(index);
856             return;
857         }
858         if (containsCommentTemplate(comment))
859             return;
860         
861         // Insert the comment as the first element
862
String JavaDoc[] newComments = new String JavaDoc[Math.min(previousComments.length + 1, maxComments)];
863         newComments[0] = comment;
864         for (int i = 1; i < newComments.length; i++) {
865             newComments[i] = previousComments[i-1];
866         }
867         previousComments = newComments;
868     }
869
870     private int getCommentIndex(String JavaDoc comment) {
871         for (int i = 0; i < previousComments.length; i++) {
872             if (previousComments[i].equals(comment)) {
873                 return i;
874             }
875         }
876         return -1;
877     }
878     
879     private void makeFirstElement(int index) {
880         String JavaDoc[] newComments = new String JavaDoc[previousComments.length];
881         newComments[0] = previousComments[index];
882         System.arraycopy(previousComments, 0, newComments, 1, index);
883         int maxIndex = previousComments.length - 1;
884         if (index != maxIndex) {
885             int nextIndex = (index + 1);
886             System.arraycopy(previousComments, nextIndex, newComments,
887                     nextIndex, (maxIndex - index));
888         }
889         previousComments = newComments;
890     }
891     
892     private void readCommentTemplates(InputStream stream) throws IOException, TeamException {
893         try {
894             SAXParserFactory factory = SAXParserFactory.newInstance();
895             SAXParser parser = factory.newSAXParser();
896             parser.parse(new InputSource JavaDoc(stream),
897                     new CommentTemplatesContentHandler());
898         } catch (SAXException JavaDoc ex) {
899             IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(
900                     CVSUIMessages.RepositoryManager_parsingProblem,
901                     new String JavaDoc[] { COMMENT_TEMPLATES_FILE }), ex);
902             throw new CVSException(status);
903         } catch (ParserConfigurationException ex) {
904             IStatus status = new CVSStatus(IStatus.ERROR, CVSStatus.ERROR, NLS.bind(
905                     CVSUIMessages.RepositoryManager_parsingProblem,
906                     new String JavaDoc[] { COMMENT_TEMPLATES_FILE }), ex);
907             throw new CVSException(status);
908         }
909     }
910     
911     protected void saveCommentTemplates() throws TeamException {
912         IPath pluginStateLocation = CVSUIPlugin.getPlugin().getStateLocation();
913         File tempFile = pluginStateLocation.append(
914                 COMMENT_TEMPLATES_FILE + ".tmp").toFile(); //$NON-NLS-1$
915
File histFile = pluginStateLocation.append(COMMENT_TEMPLATES_FILE)
916                 .toFile();
917         try {
918             XMLWriter writer = new XMLWriter(new BufferedOutputStream(
919                     new FileOutputStream(tempFile)));
920             try {
921                 writeCommentTemplates(writer);
922             } finally {
923                 writer.close();
924             }
925             if (histFile.exists()) {
926                 histFile.delete();
927             }
928             boolean renamed = tempFile.renameTo(histFile);
929             if (!renamed) {
930                 throw new TeamException(new Status(IStatus.ERROR,
931                         CVSUIPlugin.ID, TeamException.UNABLE, NLS.bind(
932                                 CVSUIMessages.RepositoryManager_rename,
933                                 new String JavaDoc[] { tempFile.getAbsolutePath() }),
934                         null));
935             }
936         } catch (IOException e) {
937             throw new TeamException(new Status(IStatus.ERROR, CVSUIPlugin.ID,
938                     TeamException.UNABLE, NLS.bind(
939                             CVSUIMessages.RepositoryManager_save,
940                             new String JavaDoc[] { histFile.getAbsolutePath() }), e));
941         }
942     }
943     
944     private void writeCommentTemplates(XMLWriter writer) {
945         writer.startTag(ELEMENT_COMMENT_TEMPLATES, null, false);
946         for (int i = 0; i < commentTemplates.length; i++)
947             writer.printSimpleTag(ELEMENT_COMMIT_COMMENT, commentTemplates[i]);
948         writer.endTag(ELEMENT_COMMENT_TEMPLATES);
949     }
950     
951     private boolean containsCommentTemplate(String JavaDoc comment) {
952         for (int i = 0; i < commentTemplates.length; i++) {
953             if (commentTemplates[i].equals(comment)) {
954                 return true;
955             }
956         }
957         return false;
958     }
959     
960     /**
961      * Get list of comment templates.
962      */

963     public String JavaDoc[] getCommentTemplates() {
964         return commentTemplates;
965     }
966     
967     public void replaceAndSaveCommentTemplates(String JavaDoc[] templates)
968             throws TeamException {
969         commentTemplates = templates;
970         saveCommentTemplates();
971     }
972 }
973
Popular Tags