View Javadoc

1   /*
2   Karma core - Core of the Karma application
3   Copyright (C) 2004  Toolforge <www.toolforge.nl>
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19  package nl.toolforge.karma.core.vc.cvsimpl;
20  
21  import nl.toolforge.karma.core.KarmaRuntimeException;
22  import nl.toolforge.karma.core.module.Module;
23  import org.apache.tools.ant.DirectoryScanner;
24  import org.netbeans.lib.cvsclient.CVSRoot;
25  import org.netbeans.lib.cvsclient.admin.Entry;
26  import org.netbeans.lib.cvsclient.admin.StandardAdminHandler;
27  
28  import java.io.BufferedReader;
29  import java.io.File;
30  import java.io.FileInputStream;
31  import java.io.FileNotFoundException;
32  import java.io.FilenameFilter;
33  import java.io.IOException;
34  import java.io.InputStreamReader;
35  import java.util.ArrayList;
36  import java.util.Arrays;
37  import java.util.Iterator;
38  import java.util.List;
39  
40  /***
41   * Helper class to execute stuff on admin files in <code>CVS</code> directories on behalf of <code>module</code>.
42   *
43   * @author D.A. Smedes
44   * @version $Id: AdminHandler.java,v 1.3 2004/11/10 23:53:09 asmedes Exp $
45   */
46  public final class AdminHandler {
47  
48    // todo this class should be made into n interface and Module should get a method to retrieve this sort of info
49    // todo subversion impl should be made.
50  
51    private Module module = null;
52  
53    private List newStuff = new ArrayList();
54    private List changedStuff = new ArrayList();
55    private List removedStuff = new ArrayList();
56  
57    private FilenameFilter filter = new FilenameFilter() {
58  
59      public boolean accept(File dir, String name) {
60        return !name.matches(".WORKING|.DYNAMIC|.STATIC|.module.info|CVS|.cvsignore") && name.matches("[^//~]+");
61      }
62    };
63  
64    public AdminHandler(Module module) {
65      this.module = module;
66    }
67  
68    /***
69     * This method should be called to administrate the module to which this AdminHandler applies. This method will
70     * determine which files and directories are new, changed or removed, but uncommitted.
71     */
72    public void administrate() {
73  
74      // Need all CVS dirs to be able to scan Entries files.
75      //
76      DirectoryScanner scanner = new DirectoryScanner();
77      scanner.setBasedir(module.getBaseDir());
78      scanner.setExcludes(new String[]{"**/CVS"});
79      scanner.scan();
80      String[] moduleDirectories = scanner.getIncludedDirectories();
81  
82      for (int i = 0; i < moduleDirectories.length; i++) {
83  
84        StandardAdminHandler h = new StandardAdminHandler();
85        try {
86  
87          // All of a directories' entries.
88          //
89          Entry[] dirEntries = h.getEntriesAsArray(new File(module.getBaseDir(), moduleDirectories[i]));
90          List entryNames = getEntryNames(dirEntries);
91  
92          // All files and directories in this directory, regardless of them being CVS managed.
93          //
94          List dirFiles = Arrays.asList(new File(module.getBaseDir(), moduleDirectories[i]).list(filter));
95  
96          // Pass 1 : locate all new files and directories
97          //
98          for (Iterator k = dirFiles.iterator(); k.hasNext();) {
99            String item = (String) k.next();
100           if (!entryNames.contains(item)) {
101             if (moduleDirectories[i].equals("")) {
102               newStuff.add(item);
103             } else {
104               newStuff.add(new File(moduleDirectories[i], item).getPath());
105             }
106           }
107         }
108 
109         // Pass 2 : locate all changed or removed files
110         //
111         for (int j = 0; j < dirEntries.length; j++) {
112 
113           Entry entry = dirEntries[j];
114           File fileEntry = new File(module.getBaseDir(), entry.getName());
115           if (entry.isUserFileToBeRemoved()) {
116             if (moduleDirectories[i].equals("")) {
117               removedStuff.add(entry.getName());
118             } else {
119               removedStuff.add(new File(moduleDirectories[i], entry.getName()).getPath());
120             }
121           } else if (fileEntry.isFile() && (entry.getLastModified() == null ? 0 : entry.getLastModified().getTime()) != fileEntry.lastModified()) {
122             if (moduleDirectories[i].equals("")) {
123               changedStuff.add(entry.getName());
124             } else {
125               changedStuff.add(new File(moduleDirectories[i], entry.getName()).getPath());
126             }
127           }
128 //          String s = (moduleDirectories[i].equals("") ? entry.getName() : new File(moduleDirectories[i], entry.getName()).getPath());
129         }
130       } catch (IOException e) {
131         e.printStackTrace();
132       }
133     }
134   }
135 
136   private List getEntryNames(Entry[] entries) {
137     List entryList = new ArrayList();
138     for (int j = 0; j < entries.length; j++) {
139       entryList.add(entries[j].getName());
140     }
141     return entryList;
142   }
143 
144   /***
145    * Returns a <code>List</code> of <code>File</code> instances indicating files and directories that are not yet
146    * version managed by CVS.
147    *
148    * @see #administrate()
149    */
150   public List getNewStuff() {
151     return newStuff;
152   }
153 
154   public boolean hasNewStuff() {
155     return newStuff.size() > 0;
156   }
157 
158   /***
159    * Returns a <code>List</code> of <code>File</code> instances indicating files that have been changed, but not yet
160    * committed.
161    *
162    * @see #administrate()
163    */
164   public List getChangedStuff() {
165     return changedStuff;
166   }
167 
168   public boolean hasChangedStuff() {
169     return changedStuff.size() > 0;
170   }
171 
172   /***
173    * Returns a <code>List</code> of <code>File</code> instances indicating files that have been removed, but not yet
174    * committed.
175    *
176    * @see #administrate()
177    */
178   public List getRemovedStuff() {
179     return removedStuff;
180   }
181 
182   public boolean hasRemovedStuff() {
183     return removedStuff.size() > 0;
184   }
185 
186 
187   /***
188    * Checks if the module was previously checked out from the same location as is stored in <code>CVS/Root</code>.
189    *
190    * @return A check is done of the CVSROOT. If they are equal, this method returns <code>true</code>.
191    */
192   public boolean isEqualLocation() {
193 
194     if (!module.getBaseDir().exists()) {
195       // if the module has not been checked out, it is OK!
196       //
197       return true;
198     }
199 
200     File rootFile = new File(module.getBaseDir(), "CVS/Root");
201 
202     String cvsRootString = null;
203     try {
204       BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(rootFile)));
205 
206       cvsRootString = in.readLine();
207       in.close();
208 
209     } catch (FileNotFoundException e) {
210       // We guess the user has created a module and not stored in a version control repository.
211       //
212       return true;
213     } catch (IOException e) {
214       throw new KarmaRuntimeException(e.getMessage());
215     }
216 
217     CVSRoot cvsRoot = CVSRoot.parse(cvsRootString);
218 
219     CVSRepository loc = (CVSRepository) module.getLocation();
220     try {
221       return cvsRoot.toString().equals(loc.getCVSRoot());
222     } catch (CVSException e) {
223       return true;
224     }
225   }
226 }