KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > resources > RemoteModule


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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  *******************************************************************************/

11 package org.eclipse.team.internal.ccvs.core.resources;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.NoSuchElementException JavaDoc;
19 import java.util.StringTokenizer JavaDoc;
20
21 import org.eclipse.core.runtime.*;
22 import org.eclipse.osgi.util.NLS;
23 import org.eclipse.team.core.TeamException;
24 import org.eclipse.team.internal.ccvs.core.*;
25 import org.eclipse.team.internal.ccvs.core.client.*;
26 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
27 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
28
29 public class RemoteModule extends RemoteFolder {
30     
31     private String JavaDoc label;
32     private ICVSRemoteResource[] referencedModules;
33     private LocalOption[] localOptions;
34     private boolean expandable;
35     
36     public static RemoteModule[] getRemoteModules(ICVSRepositoryLocation repository, CVSTag tag, IProgressMonitor monitor) throws TeamException {
37         monitor = Policy.monitorFor(monitor);
38         monitor.beginTask(CVSMessages.RemoteModule_getRemoteModules, 100);
39         try {
40             RemoteModule[] modules;
41             Session s = new Session(repository, getRemoteRootFolder(repository), false);
42             s.open(Policy.subMonitorFor(monitor, 10), false /* read-only */);
43             try {
44                 modules = Command.CHECKOUT.getRemoteModules(s, tag, Policy.subMonitorFor(monitor, 90));
45             } finally {
46                 s.close();
47             }
48             return modules;
49         } finally {
50             monitor.done();
51         }
52     }
53     
54     private static ICVSFolder getRemoteRootFolder(ICVSRepositoryLocation repository) {
55         return new RemoteFolder(null, repository, "/", null); //$NON-NLS-1$
56
}
57
58     /**
59      * Create a set of RemoteModules from the provided module definition strings returned from the server
60      *
61      * At the moment, we are very restrictive on the types of modules we support.
62      */

63     public static RemoteModule[] createRemoteModules(String JavaDoc[] moduleDefinitionStrings, ICVSRepositoryLocation repository, CVSTag tag) {
64         
65         Map JavaDoc modules = new HashMap JavaDoc();
66         Map JavaDoc referencedModulesTable = new HashMap JavaDoc();
67         Map JavaDoc moduleAliases = new HashMap JavaDoc();
68         
69         // First pass: Create the remote module instances based on remote mapping
70
for (int i = 0; i < moduleDefinitionStrings.length; i++) {
71             
72             // Read the module name
73
StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(moduleDefinitionStrings[i]);
74             String JavaDoc moduleName = tokenizer.nextToken();
75             List JavaDoc localOptionsList;
76             String JavaDoc next;
77             try {
78                 // Read the options associated with the module
79
localOptionsList = new ArrayList JavaDoc();
80                 next = tokenizer.nextToken();
81                 while (next.charAt(0) == '-') {
82                     switch (next.charAt(1)) {
83                         case 'a': // alias
84
localOptionsList.add(Checkout.ALIAS);
85                             break;
86                         case 'l': // don't recurse
87
localOptionsList.add(Command.DO_NOT_RECURSE);
88                             break;
89                         case 'd': // directory
90
localOptionsList.add(Checkout.makeDirectoryNameOption(tokenizer.nextToken()));
91                             break;
92                         case 'e':
93                         case 'i':
94                         case 'o':
95                         case 't':
96                         case 'u': // Ignore any programs
97
tokenizer.nextToken();
98                             break;
99                         case 's': // status
100
localOptionsList.add(Checkout.makeStatusOption(tokenizer.nextToken()));
101                             break;
102                         default: // unanticipated option. Ignore it and go on
103
}
104                     next = tokenizer.nextToken();
105                 }
106             } catch (NoSuchElementException JavaDoc e) {
107                 // There is an invalid entry in the modules file. Log it and continue
108
CVSProviderPlugin.log(IStatus.WARNING, NLS.bind(CVSMessages.RemoteModule_invalidDefinition, new String JavaDoc[] { moduleDefinitionStrings[i], repository.getLocation(true) }), null);
109                 continue;
110             }
111             LocalOption[] localOptions = (LocalOption[]) localOptionsList.toArray(new LocalOption[localOptionsList.size()]);
112             
113             if (Checkout.ALIAS.isElementOf(localOptions)) {
114                 
115                 if (localOptions.length > 1) {
116                     // XXX This is an error condition that needs to be reported
117
}
118                 
119                 // An alias expands to one or more modules or paths
120
List JavaDoc expansions = new ArrayList JavaDoc(10);
121                 expansions.add(next);
122                 while (tokenizer.hasMoreTokens())
123                     expansions.add(tokenizer.nextToken());
124                     
125                 moduleAliases.put(moduleName, expansions.toArray(new String JavaDoc[expansions.size()]));
126                 modules.put(moduleName, new RemoteModule(moduleName, null, repository, null, localOptions, tag, true));
127
128             } else {
129                 
130                 // The module definition may have a leading directory which can be followed by some files
131
if (!(next.charAt(0) == '&')) {
132                     String JavaDoc directory = next;
133                     List JavaDoc files = new ArrayList JavaDoc();
134                     while (tokenizer.hasMoreTokens() && (next.charAt(0) != '&')) {
135                         next = tokenizer.nextToken() ;
136                         if ((next.charAt(0) != '&'))
137                             files.add(next);
138                     }
139                     RemoteModule remoteModule = new RemoteModule(moduleName, null, repository, directory, localOptions, tag, ! files.isEmpty());
140                     modules.put(moduleName, remoteModule);
141                     if ( ! files.isEmpty()) {
142                         ICVSRemoteResource[] children = new ICVSRemoteResource[files.size()];
143                         for (int j = 0; j < children.length; j++) {
144                             children[j] = new RemoteFile(remoteModule, Update.STATE_NONE, (String JavaDoc)files.get(j), null, null, tag);
145                             remoteModule.setChildren(children);
146                         }
147                     }
148                 } else {
149                     modules.put(moduleName, new RemoteModule(moduleName, null, repository, null, localOptions, tag, true));
150                 }
151                 
152                 // Record any referenced modules so that can be cross-referenced below
153
if (next.charAt(0) == '&') {
154                     List JavaDoc children = new ArrayList JavaDoc(10);
155                     children.add(next);
156                     while (tokenizer.hasMoreTokens())
157                         children.add(tokenizer.nextToken());
158                     referencedModulesTable.put(moduleName, children.toArray(new String JavaDoc[children.size()]));
159                 }
160             }
161         }
162         
163         // Second pass: Cross reference aliases to modules
164
// XXX Aliases can reference other aliases which confuses the expansion!
165
Iterator JavaDoc iter = moduleAliases.keySet().iterator();
166         while (iter.hasNext()) {
167             String JavaDoc moduleName = (String JavaDoc)iter.next();
168             RemoteModule module = (RemoteModule)modules.get(moduleName);
169             String JavaDoc[] expansion = (String JavaDoc[])moduleAliases.get(moduleName);
170             List JavaDoc referencedFolders = new ArrayList JavaDoc();
171             boolean expandable = true;
172             for (int i = 0; i < expansion.length; i++) {
173                 if (expansion[i].charAt(0) == '!') {
174                     // XXX Unsupported for now
175
expandable = false;
176                 } else {
177                     IPath path = new Path(null, expansion[i]);
178                     if (path.segmentCount() > 1) {
179                         // XXX Unsupported for now
180
expandable = false;
181                     } else {
182                         RemoteModule child = (RemoteModule)modules.get(expansion[i]);
183                         if (child == null) {
184                             referencedFolders.add(new RemoteFolder(null, repository, path.toString(), tag));
185                         } else {
186                             // Need to check if the child is a module alias
187
if (child.isAlias()) {
188                                 // XXX Unsupported for now
189
expandable = false;
190                             } else {
191                                  referencedFolders.add(child);
192                             }
193                         }
194                     }
195                 }
196             }
197             if (expandable) {
198                 //TODO: Make module static??
199
module.setChildren((ICVSRemoteResource[]) referencedFolders.toArray(new ICVSRemoteResource[referencedFolders.size()]));
200             } else {
201                 module.setExpandable(false);
202             }
203         }
204         
205         // Third pass: Cross reference remote modules where necessary
206
iter = modules.keySet().iterator();
207         while (iter.hasNext()) {
208             String JavaDoc moduleName = (String JavaDoc)iter.next();
209             String JavaDoc[] children = (String JavaDoc[])referencedModulesTable.get(moduleName);
210             if (children != null) {
211                 RemoteModule module = (RemoteModule)modules.get(moduleName);
212                 List JavaDoc referencedFolders = new ArrayList JavaDoc();
213                 boolean expandable = true;
214                 for (int i = 0; i < children.length; i++) {
215                     RemoteModule child = (RemoteModule)modules.get(children[i].substring(1));
216                     if (child == null) {
217                         // invalid module definition
218
expandable = false;
219                     } else if (child.isAlias()) {
220                         // Include alias children in-line
221
expandable = false;
222 // referencedFolders.addAll(Arrays.asList(child.getChildren()));
223
} else {
224                         // XXX not expandable if child has local directory option (-d)
225
if (Command.findOption(child.getLocalOptions(), "-d") != null) { //$NON-NLS-1$
226
expandable = false;
227                         } else {
228                             referencedFolders.add(child);
229                         }
230                     }
231                 }
232                 if (expandable) {
233                     module.setReferencedModules((ICVSRemoteResource[]) referencedFolders.toArray(new ICVSRemoteResource[referencedFolders.size()]));
234                 } else {
235                     module.setExpandable(false);
236                 }
237             }
238         }
239                         
240         return (RemoteModule[])modules.values().toArray(new RemoteModule[modules.size()]);
241     }
242         
243     public RemoteModule(String JavaDoc label, RemoteFolder parent, ICVSRepositoryLocation repository, String JavaDoc repositoryRelativePath, LocalOption[] localOptions, CVSTag tag, boolean isStatic) {
244         super(parent,
245             label,
246             repository,
247             repositoryRelativePath == null ? FolderSyncInfo.VIRTUAL_DIRECTORY : repositoryRelativePath,
248             tag,
249             isStatic);
250         this.localOptions = localOptions;
251         this.label = label;
252         this.expandable = true;
253     }
254     
255     public LocalOption[] getLocalOptions() {
256         return localOptions;
257     }
258     /*
259      * Override of inherited getMembers in order to combine the physical members with any referenced modules
260      */

261     public ICVSRemoteResource[] getMembers(CVSTag tagName, IProgressMonitor monitor) throws CVSException {
262         
263         if ( ! expandable) return new ICVSRemoteResource[0];
264         
265         ICVSRemoteResource[] physicalChildren;
266         if ( folderInfo.getIsStatic()) {
267             physicalChildren = getChildren();
268         } else {
269             physicalChildren = super.getMembers(tagName, monitor);
270         }
271         ICVSRemoteResource[] allChildren;
272         if (referencedModules != null && referencedModules.length > 0) {
273             if (physicalChildren == null) {
274                 allChildren = referencedModules;
275             } else {
276                 // Combine two sets of children
277
allChildren = new ICVSRemoteResource[physicalChildren.length + referencedModules.length];
278                 for (int i = 0; i < physicalChildren.length; i++) {
279                     allChildren[i] = physicalChildren[i];
280                 }
281                 for (int i = 0; i < referencedModules.length; i++) {
282                     allChildren[i + physicalChildren.length] = referencedModules[i];
283                 }
284             }
285         } else if (physicalChildren != null) {
286             allChildren = physicalChildren;
287         } else {
288             allChildren = new ICVSRemoteResource[0];
289         }
290         return allChildren;
291     }
292     
293     private void setReferencedModules(ICVSRemoteResource[] referencedModules) {
294         this.referencedModules = referencedModules;
295     }
296     
297     public boolean isAlias() {
298         return Checkout.ALIAS.isElementOf(localOptions);
299     }
300     
301     /**
302      * @see ICVSRemoteFolder#isExpandable()
303      */

304     public boolean isExpandable() {
305         return expandable;
306     }
307     
308     private void setExpandable(boolean expandable) {
309         this.expandable = expandable;
310     }
311     
312     /**
313      * @see ICVSRemoteFolder#forTag(CVSTag)
314      */

315     public ICVSRemoteResource forTag(ICVSRemoteFolder parent, CVSTag tagName) {
316         RemoteModule r = new RemoteModule(label, (RemoteFolder)parent, getRepository(), folderInfo.getRepository(), localOptions, tagName, folderInfo.getIsStatic());
317         r.setExpandable(expandable);
318         if (folderInfo.getIsStatic()) {
319             ICVSRemoteResource[] children = getChildren();
320             if (children != null) {
321                 List JavaDoc taggedChildren = new ArrayList JavaDoc(children.length);
322                 for (int i = 0; i < children.length; i++) {
323                     ICVSRemoteResource resource = children[i];
324                     taggedChildren.add(((RemoteResource)resource).forTag(r, tagName));
325                 }
326                 r.setChildren((ICVSRemoteResource[]) taggedChildren.toArray(new ICVSRemoteResource[taggedChildren.size()]));
327             }
328         }
329         if (referencedModules != null) {
330             List JavaDoc taggedModules = new ArrayList JavaDoc(referencedModules.length);
331             for (int i = 0; i < referencedModules.length; i++) {
332                 RemoteModule module = (RemoteModule)referencedModules[i];
333                 taggedModules.add(module.forTag(r, tagName));
334             }
335             r.setReferencedModules((ICVSRemoteResource[]) taggedModules.toArray(new ICVSRemoteResource[taggedModules.size()]));
336         }
337         return r;
338     }
339     
340     /**
341      * @see org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder#isDefinedModule()
342      */

343     public boolean isDefinedModule() {
344         return true;
345     }
346     /**
347      * @see java.lang.Object#equals(java.lang.Object)
348      */

349     public boolean equals(Object JavaDoc arg0) {
350         if (arg0 instanceof RemoteModule) {
351             RemoteModule module = (RemoteModule) arg0;
352             return (getName().equals(module.getName()) && super.equals(module));
353         }
354         return false;
355     }
356     
357     /**
358      * @see java.lang.Object#hashCode()
359      */

360     public int hashCode() {
361         return super.hashCode() | getName().hashCode();
362     }
363
364     /**
365      * @see org.eclipse.team.internal.ccvs.core.ICVSFolder#getChild(java.lang.String)
366      */

367     public ICVSResource getChild(String JavaDoc path) throws CVSException {
368         if (path.equals(Session.CURRENT_LOCAL_FOLDER) || path.length() == 0)
369             return this;
370         // If the path is one segment and it's a referenced module, return the module
371
// Note: the overriden method will extract the first segment from a multi segment
372
// path and re-invoke this method so we only need to check for one segment here
373
// and use the inherited method in the other cases
374
if (referencedModules != null) {
375             if (path.indexOf(Session.SERVER_SEPARATOR) == -1) {
376                 for (int i=0;i<referencedModules.length;i++) {
377                     if (referencedModules[i].getName().equals(path))
378                         return referencedModules[i];
379                 }
380             }
381         }
382         return super.getChild(path);
383     }
384
385 }
386
Popular Tags