KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > versioning > VersioningManager


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.versioning;
20
21 import org.netbeans.modules.versioning.spi.VersioningSystem;
22 import org.netbeans.modules.versioning.spi.VCSContext;
23 import org.netbeans.modules.versioning.spi.LocalHistory;
24 import org.netbeans.modules.versioning.util.Utils;
25 import org.netbeans.modules.masterfs.providers.InterceptionListener;
26 import org.openide.util.Lookup;
27 import org.openide.util.LookupListener;
28 import org.openide.util.LookupEvent;
29
30 import java.io.File JavaDoc;
31 import java.util.*;
32 import java.beans.PropertyChangeListener JavaDoc;
33 import java.beans.PropertyChangeEvent JavaDoc;
34
35 /**
36  * Top level versioning manager that mediates communitation between IDE and registered versioning systems.
37  *
38  * @author Maros Sandor
39  */

40 public class VersioningManager implements PropertyChangeListener JavaDoc, LookupListener {
41     
42     private static VersioningManager instance;
43
44     public static synchronized VersioningManager getInstance() {
45         if (instance == null) {
46             instance = new VersioningManager();
47             instance.init();
48         }
49         return instance;
50     }
51
52     // ======================================================================================================
53

54     private final FilesystemInterceptor filesystemInterceptor;
55
56     /**
57      * Manager of Versioning Output components.
58      */

59     private final VersioningOutputManager outputManager = new VersioningOutputManager();
60     
61     /**
62      * Holds all registered versioning systems.
63      */

64     private final Collection<VersioningSystem> versioningSystems = new ArrayList<VersioningSystem>(2);
65
66     /**
67      * What folder is versioned by what versioning system.
68      */

69     private final Map<File JavaDoc, VersioningSystem> folderOwners = new WeakHashMap<File JavaDoc, VersioningSystem>(100);
70
71     /**
72      * Holds registered local history system.
73      */

74     private VersioningSystem localHistory;
75     
76     /**
77      * What folders are managed by local history.
78      */

79     private Map<File JavaDoc, Boolean JavaDoc> localHistoryFolders = new WeakHashMap<File JavaDoc, Boolean JavaDoc>(100);
80     
81     private final VersioningSystem NULL_OWNER = new VersioningSystem() {
82         public String JavaDoc getDisplayName() {
83             return null;
84         }
85     };
86     
87     private VersioningManager() {
88         filesystemInterceptor = new FilesystemInterceptor();
89     }
90     
91     private void init() {
92         initVersioningSystems();
93         filesystemInterceptor.init(this);
94     }
95
96     private void initVersioningSystems() {
97         Lookup.Result<VersioningSystem> result = Lookup.getDefault().lookup(new Lookup.Template<VersioningSystem>(VersioningSystem.class));
98         refreshVersioningSystems(result.allInstances());
99         result.addLookupListener(this);
100     }
101
102     /**
103      * List of versioning systems changed.
104      *
105      * @param systems new list of versioning systems
106      */

107     private void refreshVersioningSystems(Collection<? extends VersioningSystem> systems) {
108         synchronized(versioningSystems) {
109             unloadVersioningSystems();
110             loadVersioningSystems(systems);
111         }
112     }
113
114     private void loadVersioningSystems(Collection<? extends VersioningSystem> systems) {
115         assert versioningSystems.size() == 0;
116         assert localHistory == null;
117         versioningSystems.addAll(systems);
118         for (VersioningSystem system : versioningSystems) {
119             if (localHistory == null && system instanceof LocalHistory) {
120                 localHistory = system;
121             }
122             system.addPropertyChangeListener(this);
123         }
124     }
125
126     private void unloadVersioningSystems() {
127         for (VersioningSystem system : versioningSystems) {
128             system.removePropertyChangeListener(this);
129         }
130         versioningSystems.clear();
131         localHistory = null;
132     }
133
134     InterceptionListener getInterceptionListener() {
135         return filesystemInterceptor;
136     }
137
138     private synchronized void flushFileOwnerCache() {
139         folderOwners.clear();
140         localHistoryFolders.clear();
141     }
142
143     synchronized VersioningSystem[] getVersioningSystems() {
144         return versioningSystems.toArray(new VersioningSystem[versioningSystems.size()]);
145     }
146
147     /**
148      * Determines versioning systems that manage files in given context.
149      *
150      * @param ctx VCSContext to examine
151      * @return VersioningSystem systems that manage this context or an empty array if the context is not versioned
152      */

153     VersioningSystem[] getOwners(VCSContext ctx) {
154         Set<File JavaDoc> files = ctx.getRootFiles();
155         Set<VersioningSystem> owners = new HashSet<VersioningSystem>();
156         for (File JavaDoc file : files) {
157             VersioningSystem vs = getOwner(file);
158             if (vs != null) {
159                 owners.add(vs);
160             }
161         }
162         return (VersioningSystem[]) owners.toArray(new VersioningSystem[owners.size()]);
163     }
164
165     /**
166      * Determines the versioning system that manages given file.
167      * Owner of a file:
168      * - annotates its label in explorers, editor tab, etc.
169      * - provides menu actions for it
170      * - supplies "original" content of the file
171      *
172      * Owner of a file may change over time (one common example is the Import command). In such case, the appropriate
173      * Versioning System is expected to fire the PROP_VERSIONED_ROOTS property change.
174      *
175      * @param file a file
176      * @return VersioningSystem owner of the file or null if the file is not under version control
177      */

178     public synchronized VersioningSystem getOwner(File JavaDoc file) {
179         File JavaDoc folder = file;
180         if (file.isFile()) {
181             folder = file.getParentFile();
182             if (folder == null) return null;
183         }
184         
185         VersioningSystem owner = folderOwners.get(folder);
186         if (owner == NULL_OWNER) return null;
187         if (owner != null) return owner;
188         
189         File JavaDoc closestParent = null;
190             for (VersioningSystem system : versioningSystems) {
191                 if (system != localHistory) { // currently, local history is never an owner of a file
192
File JavaDoc topmost = system.getTopmostManagedParent(folder);
193                     if (topmost != null && (closestParent == null || Utils.isParentOrEqual(closestParent, topmost))) {
194                         owner = system;
195                         closestParent = topmost;
196                     }
197                 }
198             }
199                 
200         if (owner != null) {
201             folderOwners.put(folder, owner);
202         } else {
203             folderOwners.put(folder, NULL_OWNER);
204         }
205         return owner;
206     }
207
208     /**
209      * Returns local history module that handles the given file.
210      *
211      * @param file the file to examine
212      * @return VersioningSystem local history versioning system or null if there is no local history for the file
213      */

214     synchronized VersioningSystem getLocalHistory(File JavaDoc file) {
215         if (localHistory == null) return null;
216         File JavaDoc folder = file;
217         if (file.isFile()) {
218             folder = file.getParentFile();
219             if (folder == null) return null;
220         }
221         
222         Boolean JavaDoc isManagedByLocalHistory = localHistoryFolders.get(folder);
223         if (isManagedByLocalHistory != null) {
224             return isManagedByLocalHistory ? localHistory : null;
225         }
226                 
227         boolean isManaged = localHistory.getTopmostManagedParent(folder) != null;
228         if (isManaged) {
229             localHistoryFolders.put(folder, Boolean.TRUE);
230             return localHistory;
231         } else {
232             localHistoryFolders.put(folder, Boolean.FALSE);
233             return null;
234         }
235     }
236     
237     public VersioningOutputManager getOutputManager() {
238         return outputManager;
239     }
240
241     public void resultChanged(LookupEvent ev) {
242         Lookup.Result<VersioningSystem> result = (Lookup.Result<VersioningSystem>) ev.getSource();
243         refreshVersioningSystems(result.allInstances());
244     }
245
246     /**
247      * Versioning status or other parameter changed.
248      */

249     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
250         if (VersioningSystem.PROP_STATUS_CHANGED.equals(evt.getPropertyName())) {
251             Set<File JavaDoc> files = (Set<File JavaDoc>) evt.getNewValue();
252             VersioningAnnotationProvider.instance.refreshAnnotations(files);
253         } else if (VersioningSystem.PROP_ANNOTATIONS_CHANGED.equals(evt.getPropertyName())) {
254             Set<File JavaDoc> files = (Set<File JavaDoc>) evt.getNewValue();
255             VersioningAnnotationProvider.instance.refreshAnnotations(files);
256         } else if (VersioningSystem.PROP_VERSIONED_ROOTS.equals(evt.getPropertyName())) {
257             flushFileOwnerCache();
258         }
259     }
260 }
261
Popular Tags