1 package net.sf.jpkgmk.prototype;
2
3 import java.io.File;
4 import java.io.FileFilter;
5 import java.io.IOException;
6 import java.util.Arrays;
7 import java.util.Comparator;
8
9 import net.sf.jpkgmk.DefaultPermissionProvider;
10 import net.sf.jpkgmk.FileHandler;
11 import net.sf.jpkgmk.PermissionProvider;
12 import net.sf.jpkgmk.util.FileUtil;
13 import net.sf.jpkgmk.util.StringUtil;
14
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17
18
19
20
21
22
23
24
25
26 public class PrototypeBuilder
27 {
28 private Log log = LogFactory.getLog(PrototypeBuilder.class);
29
30 private String defaultUser="root";
31 private String defaultGroup="other";
32 private PermissionProvider defaultPermissionProvider=new DefaultPermissionProvider();
33
34 private Prototype prototype;
35
36 private File basedir;
37
38 private Comparator<File> dirFirstComparator = new Comparator<File>() {
39
40 public int compare(File o1, File o2) {
41 if(o1.isDirectory() && o2.isDirectory()) {
42 return o1.compareTo(o2);
43 }
44 else if(o1.isFile() && o2.isFile()) {
45 return o1.compareTo(o2);
46 }
47 else if(o1.isDirectory()) {
48 return -1;
49 }
50 else if(o2.isDirectory()) {
51 return 1;
52 }
53 return 0;
54 }
55
56 };
57
58
59
60
61
62 public PrototypeBuilder()
63 {
64 this(null, null, null, null);
65 }
66
67
68
69
70 public PrototypeBuilder(File basedir)
71 {
72 this(basedir, null, null, null);
73 }
74
75
76
77
78 public PrototypeBuilder(File basedir, String defaultUser, String defaultGroup)
79 {
80 this(basedir, defaultUser, defaultGroup, null);
81 }
82
83
84
85
86
87
88
89 public PrototypeBuilder(File basedir, String defaultUser, String defaultGroup, PermissionProvider defaultPermissionProvider)
90 {
91 this.basedir = basedir;
92
93 if(!StringUtil.isNullOrEmpty(defaultUser)) {
94 this.defaultUser = defaultUser;
95 }
96 if(!StringUtil.isNullOrEmpty(defaultGroup)) {
97 this.defaultGroup = defaultGroup;
98 }
99 if(defaultPermissionProvider != null) {
100 this.defaultPermissionProvider = defaultPermissionProvider;
101 }
102 this.prototype = new Prototype();
103 }
104
105 public String getDefaultUser() {
106 return defaultUser;
107 }
108
109 public String getDefaultGroup() {
110 return defaultGroup;
111 }
112
113 public Prototype getPrototype()
114 {
115 return this.prototype;
116 }
117
118
119 public void add(PrototypeEntry prototypeEntry) {
120 this.prototype.add(prototypeEntry);
121 }
122
123
124 public void addLink(String linkLocation, PrototypeEntryFile entry) {
125 PrototypeEntryLink link = new PrototypeEntryLink(linkLocation, entry.getEntryPath());
126 this.add(link);
127 }
128
129 public void addFile(File sourceFile) throws IOException
130 {
131 this.addFile(sourceFile, PrototypeEntryType.F, null);
132 }
133
134 public PrototypeEntryFile addFile(File sourceFile, PrototypeEntryType type) throws IOException
135 {
136 return this.addFile(sourceFile, type, null);
137 }
138
139 public PrototypeEntryFile addFile(File sourceFile, PrototypeEntryType type, String targetPathForPackage) throws IOException
140 {
141 if (sourceFile == null) {
142 throw new NullPointerException(
143 "The parameter 'sourceFile' must not be null");
144 }
145 if (type == null) {
146 throw new NullPointerException(
147 "The parameter 'type' must not be null");
148 }
149
150 if(!sourceFile.isFile()) {
151 throw new IllegalArgumentException("The file '" + sourceFile + "' must be a file");
152 }
153
154 PrototypeEntryFile entry = addFileInternal(sourceFile, targetPathForPackage, this.defaultUser, this.defaultGroup, this.defaultPermissionProvider, type);
155 return entry;
156 }
157
158
159
160
161
162
163
164 public void addDirectory(File directory)
165 {
166 this.addDirectory(directory, true);
167 }
168
169
170
171
172
173
174
175 public void addDirectory(File directory, boolean recurse)
176 {
177 this.addDirectory(directory, null, null, null, null, null, recurse);
178 }
179
180
181
182
183
184
185
186 public void addDirectory(File directory, String targetPathDir)
187 {
188 this.addDirectory(directory, targetPathDir, null, null, null);
189 }
190
191
192
193
194
195
196
197
198
199
200 public void addDirectory(File directory, String targetPathDir, String owner, String group, PermissionProvider permissionProvider)
201 {
202 this.addDirectory(directory, targetPathDir, owner, group, permissionProvider, null, true);
203 }
204
205
206
207
208
209
210
211
212
213
214
215
216 public void addDirectory(File directory, String targetPathDir, String owner, String group, PermissionProvider permissionProvider, FileFilter fileFilter, boolean recurse)
217 {
218 log.debug("adding directory '" + directory + "'");
219
220 if(directory == null) {
221 throw new NullPointerException("The parameter 'directory' must not be null");
222 }
223 if(!directory.isDirectory()) {
224 throw new IllegalArgumentException("The given directory '" + directory + "' is not a directory.");
225 }
226
227 if(StringUtil.isNullOrEmpty(owner)) {
228 owner = this.defaultUser;
229 }
230 if(StringUtil.isNullOrEmpty(group)) {
231 group = this.defaultGroup;
232 }
233 if(permissionProvider == null) {
234 permissionProvider = this.defaultPermissionProvider;
235 }
236
237 addDirectoryInternal(directory, targetPathDir, owner, group, permissionProvider, fileFilter, recurse);
238 }
239
240
241 protected void addDirectoryInternal(File directory, String targetPathDir, String owner, String group, PermissionProvider permissionProvider, FileFilter fileFilter, boolean recurse)
242 {
243 log.debug("adding directory '" + directory + "'");
244
245 if(!directory.isDirectory()) {
246 throw new IllegalArgumentException("The given file must be a directory: '" + directory + "'");
247 }
248
249
250
251 File[] children = null;
252 if(fileFilter == null) {
253 children = directory.listFiles();
254 }
255 else {
256 children = directory.listFiles(fileFilter);
257 }
258
259 if(children != null) {
260 Arrays.sort(children, this.dirFirstComparator);
261
262
263 for (int i = 0; i < children.length; i++) {
264 File currentFile = children[i];
265
266 String currentPathForTarget;
267 if(targetPathDir==null) {
268 currentPathForTarget = currentFile.getName();
269 }
270 else {
271
272 String perm = permissionProvider.getMode(directory);
273 PrototypeEntry entry = new PrototypeEntryDirectory(null, AbstractPrototypeEntry.DEFAULT_FILE_CLASS, targetPathDir, perm, owner, group, null);
274 if(!this.prototype.contains(entry)) {
275 this.prototype.add(entry);
276 }
277 currentPathForTarget = targetPathDir + FileUtil.UNIX_FILE_SEPARATOR + currentFile.getName();
278 }
279
280 if(currentFile.isDirectory()) {
281
282 createAndAddDirEntry(currentFile, currentPathForTarget, owner, group, permissionProvider, PrototypeEntryType.D);
283
284 if(recurse) {
285 log.debug("Recursive call for subdir '" + currentFile + "'");
286 addDirectoryInternal(currentFile, currentPathForTarget, owner, group, permissionProvider, fileFilter, recurse);
287 }
288 else {
289 log.debug("No recursive call is done for subdir '" + currentFile + "'");
290 }
291 }
292 else {
293 addFileInternal(currentFile, currentPathForTarget, owner, group, permissionProvider, PrototypeEntryType.F);
294 }
295 }
296 }
297 }
298
299
300 private String resolveFilePathOnTarget(String inputFilePathOnTarget, File currentFile) {
301 if(inputFilePathOnTarget == null) {
302 inputFilePathOnTarget = currentFile.getName();
303 log.debug("No 'filePathOnTarget' specified - defaulting to '" + inputFilePathOnTarget + "'.");
304 }
305 return inputFilePathOnTarget;
306 }
307
308 private void createAndAddDirEntry(File currentFile, String filePathOnTarget, String owner, String group, PermissionProvider permissionProvider, PrototypeEntryType entryType)
309 {
310 String perm = permissionProvider.getMode(currentFile);
311 filePathOnTarget = resolveFilePathOnTarget(filePathOnTarget,currentFile);
312
313 PrototypeEntry entry;
314 if(entryType == PrototypeEntryType.D) {
315 entry = new PrototypeEntryDirectory(null, AbstractPrototypeEntry.DEFAULT_FILE_CLASS, filePathOnTarget, perm, owner, group, null);
316 }
317 else if(entryType == PrototypeEntryType.X) {
318 entry = new PrototypeEntryDirectoryExclusive(null, AbstractPrototypeEntry.DEFAULT_FILE_CLASS, filePathOnTarget, perm, owner, group, null);
319 }
320 else {
321 throw new IllegalArgumentException("The entryType '" + entryType + "' is not yet supported");
322 }
323
324 this.prototype.add(entry);
325 }
326
327
328 protected PrototypeEntryFile addFileInternal(File currentFile, String filePathOnTarget, String owner, String group, PermissionProvider permissionProvider, PrototypeEntryType entryType)
329 {
330 String perm = permissionProvider.getMode(currentFile);
331 String sourceFile = currentFile.getAbsolutePath();
332 filePathOnTarget = resolveFilePathOnTarget(filePathOnTarget,currentFile);
333
334 PrototypeEntryFile entry;
335 if(entryType == PrototypeEntryType.F) {
336 entry = new PrototypeEntryFile(null, AbstractPrototypeEntry.DEFAULT_FILE_CLASS, filePathOnTarget, sourceFile, perm, owner, group, null);
337 }
338 else if(entryType == PrototypeEntryType.E) {
339 entry = new PrototypeEntryFileEditable(null, AbstractPrototypeEntry.DEFAULT_FILE_CLASS, filePathOnTarget, sourceFile, perm, owner, group, null);
340 }
341 else if(entryType == PrototypeEntryType.V) {
342 entry = new PrototypeEntryFileVolatile(null, AbstractPrototypeEntry.DEFAULT_FILE_CLASS, filePathOnTarget, sourceFile, perm, owner, group, null);
343 }
344 else if(entryType == PrototypeEntryType.I) {
345 entry = new PrototypeEntryInfo(null, filePathOnTarget, sourceFile);
346 }
347
348
349
350
351
352
353
354 else {
355 throw new IllegalArgumentException("The entryType '" + entryType + "' is not yet supported");
356 }
357
358
359
360
361 this.prototype.add(entry);
362 return entry;
363 }
364
365
366 private void checkBasedirIsSet(){
367 if (basedir == null) {
368 throw new NullPointerException("The attribute 'basedir' must not be null");
369 }
370 }
371
372 public File clean() {
373 checkBasedirIsSet();
374 getPrototype().clean(basedir);
375 return getFile();
376 }
377
378 public File create() throws IOException {
379 checkBasedirIsSet();
380 getPrototype().create(basedir);
381 return getFile();
382 }
383
384 public File getFile(){
385 checkBasedirIsSet();
386 FileHandler fileHandler = getPrototype().getFileHandler(basedir);
387 return fileHandler.getFile();
388 }
389
390 @Override
391 public String toString()
392 {
393 StringBuffer sb = new StringBuffer();
394 sb.append(getClass().getName()).append("[");
395 sb.append("basedir=").append(basedir);
396 sb.append(",defaultUser=").append(defaultUser);
397 sb.append(",defaultGroup=").append(defaultGroup);
398 sb.append(",defaultPermissionProvider=").append(defaultPermissionProvider);
399 sb.append(",prototype=").append(this.prototype);
400 sb.append("]");
401 return sb.toString();
402 }
403
404 }