1 package net.sf.jpkgmk.prototype;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import net.sf.jpkgmk.AbstractLineProvider;
9 import net.sf.jpkgmk.pkgmap.PkgMapEntry;
10 import net.sf.jpkgmk.pkgmap.PkgMapEntryType;
11 import net.sf.jpkgmk.util.FileUtil;
12 import net.sf.jpkgmk.util.StringUtil;
13 import net.sf.jpkgmk.util.VariableMap;
14 import net.sf.jpkgmk.util.VariableResolver;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18
19
20
21
22
23
24
25
26 public abstract class AbstractPrototypeEntry extends AbstractLineProvider implements PrototypeEntry
27 {
28 private Log log = LogFactory.getLog(AbstractPrototypeEntry.class);
29
30 public static final String DEFAULT_FILE_CLASS = "none";
31
32
33
34
35
36
37
38 private Integer part;
39 private PrototypeEntryType type;
40 private String entryPath;
41 private String entryPathSource;
42 private String fileClass;
43 private Integer major;
44 private Integer minor;
45 private String mode;
46 private String owner;
47 private String group;
48
49
50
51 private PrototypeEntryCommandDefault entryCommandDefault;
52
53
54
55
56
57
58
59 public AbstractPrototypeEntry(PrototypeEntryType fileType, String entryPath)
60 {
61 this(fileType, null, entryPath, null, null, null, null, null);
62 }
63
64
65
66
67
68
69
70
71
72 public AbstractPrototypeEntry(PrototypeEntryType fileType, String entryPath, String mode, String owner, String group)
73 {
74 this(fileType, null, entryPath, null, mode, owner, group, null);
75 }
76
77
78
79
80
81
82
83
84
85
86 public AbstractPrototypeEntry(PrototypeEntryType fileType, String fileClass, String entryPath, String entryPathSource, String mode, String owner, String group, PrototypeEntryCommandDefault entryCommandDefault)
87 {
88 this(null, fileType, fileClass, entryPath, entryPathSource, null, null, mode, owner, group, entryCommandDefault);
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102 public AbstractPrototypeEntry(Integer part, PrototypeEntryType fileType, String fileClass, String entryPath, String entryPathSource, String mode, String owner, String group, PrototypeEntryCommandDefault entryCommandDefault)
103 {
104 this(part, fileType, fileClass, entryPath, entryPathSource, null, null, mode, owner, group, entryCommandDefault);
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 public AbstractPrototypeEntry(Integer part, PrototypeEntryType fileType, String fileClass, String entryPath, String entryPathSource, Integer major, Integer minor, String mode, String owner, String group, PrototypeEntryCommandDefault entryCommandDefault)
122 {
123
124 if(fileType == null) {
125 throw new NullPointerException("The parameter 'fileType' must not be null");
126 }
127 if(entryPath == null) {
128 throw new NullPointerException("The parameter 'entryPath' must not be null");
129 }
130
131 if(fileClass != null) {
132 validateFileClass(fileClass);
133 }
134
135 if(mode!=null && !VariableMap.containsVariable(mode)) {
136 StringUtil.validateMode(mode);
137 }
138
139 if(owner!=null && !VariableMap.containsVariable(owner)) {
140 validateOwner(owner);
141 }
142 if(group!=null && !VariableMap.containsVariable(group)) {
143 validateGroup(group);
144 }
145
146
147
148 this.part = part;
149 this.type = fileType;
150 this.fileClass = fileClass;
151 this.entryPath = entryPath;
152 this.entryPathSource = entryPathSource;
153 this.mode = mode;
154 this.owner = owner;
155 this.group = group;
156 this.major = major;
157 this.minor = minor;
158 this.entryCommandDefault = entryCommandDefault;
159 }
160
161 private void validateOwner(String owner) {
162 int maxOwnerLength = 14;
163 if(owner.length() > maxOwnerLength) {
164 throw new IllegalArgumentException("The given owner '" + owner + "' exceeds the maximum allowed length of " + maxOwnerLength);
165 }
166 }
167
168 private void validateGroup(String group) {
169 int maxGroupLength = 14;
170 if(group.length() > maxGroupLength) {
171 throw new IllegalArgumentException("The given group '" + group + "' exceeds the maximum allowed length of " + maxGroupLength);
172 }
173 }
174
175 private void validateFileClass(String fileClassToValidate) {
176 int maxClassLength = 12;
177 if(fileClassToValidate.length() > maxClassLength) {
178 throw new IllegalArgumentException("The given class '" + fileClassToValidate + "' exceeds the maximum allowed length of " + maxClassLength);
179 }
180
181 if(!StringUtil.isAlphaNumeric(fileClassToValidate)) {
182 throw new IllegalArgumentException("The given class '" + fileClassToValidate + "' is not alphanumeric.");
183 }
184
185
186 if(fileClassToValidate.equals("admin")) {
187 throw new IllegalArgumentException("The given class '" + fileClassToValidate + "' is a reserved word and must not be used ('admin' is a reserved word).");
188 }
189 if(Character.isUpperCase(fileClassToValidate.charAt(0))) {
190 throw new IllegalArgumentException("The given class '" + fileClassToValidate + "' is a reserved word and must not be used (it begins with a capital letter).");
191 }
192 }
193
194
195
196
197
198
199
200
201
202
203
204 private String createLine()
205 {
206 StringBuffer completeLine = new StringBuffer();
207
208 if(this.part != null) {
209 completeLine.append(this.part);
210 }
211
212 if(completeLine.length()>0) {
213 completeLine.append(" ");
214 }
215 completeLine.append(type.getKey());
216
217
218 if(!StringUtil.isNullOrEmpty(fileClass)) {
219 completeLine.append(" ").append(fileClass);
220 }
221
222 completeLine.append(" ").append(entryPath);
223 if(!StringUtil.isNullOrEmpty(entryPathSource)) {
224 completeLine.append("=").append(entryPathSource);
225 }
226 if(major != null) {
227 completeLine.append(" ").append(major);
228 }
229 if(minor != null) {
230 completeLine.append(" ").append(minor);
231 }
232 if(!StringUtil.isNullOrEmpty(mode)) {
233 completeLine.append(" ").append(mode);
234 }
235 if(!StringUtil.isNullOrEmpty(owner)) {
236 completeLine.append(" ").append(owner);
237 }
238 if(!StringUtil.isNullOrEmpty(group)) {
239 completeLine.append(" ").append(group);
240 }
241 return completeLine.toString();
242 }
243
244
245 public String getLine()
246 {
247 return this.createLine();
248 }
249
250 public PrototypeEntryType getType() {
251 return this.type;
252 }
253
254 public String getEntryPath() {
255 return entryPath;
256 }
257
258 public String getEntryPathSource() {
259 return entryPathSource;
260 }
261
262 public String getFileClass() {
263 return fileClass;
264 }
265
266 public String getMode() {
267 return mode;
268 }
269
270 public String getOwner() {
271 return owner;
272 }
273
274 public String getGroup() {
275 return group;
276 }
277
278
279 public Integer getMajor() {
280 return major;
281 }
282
283 public Integer getMinor() {
284 return minor;
285 }
286
287 protected final String resolveMode() {
288 if(!StringUtil.isNullOrEmpty(this.mode)) {
289 return this.mode;
290 }
291 else if(entryCommandDefault != null){
292 return entryCommandDefault.getMode();
293 }
294 else {
295 return null;
296 }
297 }
298
299 protected final String resolveOwner()
300 {
301 if(!StringUtil.isNullOrEmpty(this.owner)) {
302 return this.owner;
303 }
304 else if(entryCommandDefault != null){
305 return entryCommandDefault.getOwner();
306 }
307 else {
308 return null;
309 }
310 }
311
312 protected final String resolveGroup()
313 {
314 if(!StringUtil.isNullOrEmpty(this.group)) {
315 return this.group;
316 }
317 else if(entryCommandDefault != null){
318 return entryCommandDefault.getGroup();
319 }
320 else {
321 return null;
322 }
323 }
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 protected File buildAbsolutePath(File targetDir, String prototypeEntryPath)
339 {
340 File target;
341
342 if(FileUtil.isRelocatable(prototypeEntryPath)) {
343 target = new File(targetDir, prototypeEntryPath);
344 }
345 else {
346 target = new File(prototypeEntryPath);
347 }
348 return target;
349 }
350
351
352
353
354
355 public final void create(File targetDir, VariableResolver variableResolver) throws IOException
356 {
357 String expandedEntryPath = variableResolver.expand(entryPath);
358 String expandedEntryPathSource = variableResolver.expand(entryPathSource);
359 this.create(targetDir, expandedEntryPath, expandedEntryPathSource);
360 }
361
362
363
364
365 protected abstract void create(File targetDir, String entryPathExpanded, String entryPathSourceExpanded) throws IOException;
366
367
368
369
370
371 public List<PkgMapEntry> createPkgMapEntry(File targetDir, VariableResolver variableResolver) {
372
373 if (variableResolver == null) {
374 throw new NullPointerException("The parameter 'variableResolver' must not be null");
375 }
376
377 PkgMapEntryType resultType = this.type.getPkgMapEntryType();
378
379 String expandedEntryPath = variableResolver.expand(entryPath);
380 String expandedEntryPathSource = variableResolver.expand(entryPathSource);
381
382 String entryClass = null;
383 if(StringUtil.isNullOrEmpty(this.fileClass)) {
384 entryClass = DEFAULT_FILE_CLASS;
385 log.debug("entryClass is null. Defaulting the file class to " + fileClass + "' for entry " + this);
386 }
387 else {
388 entryClass =this.fileClass;
389 }
390
391
392 String mode = resolveMode();
393 mode = variableResolver.expand(mode);
394 String owner = resolveOwner();
395 owner = variableResolver.expand(owner);
396 String group = resolveGroup();
397 group = variableResolver.expand(group);
398
399 if(mode!=null)
400 StringUtil.validateMode(mode);
401 if(owner!=null)
402 validateOwner(owner);
403 if(group!=null)
404 validateGroup(group);
405
406
407
408 PkgMapEntry resultEntry = createPkgMapEntry(this.part, resultType, entryClass, expandedEntryPath, expandedEntryPathSource, major, minor, mode, owner, group, targetDir);
409
410 List<PkgMapEntry> result = new ArrayList<PkgMapEntry>();
411 result.add(resultEntry);
412 return result;
413 }
414
415 protected abstract PkgMapEntry createPkgMapEntry(Integer part,
416 PkgMapEntryType resultType, String entryClass, String entryPath, String entryPathSource,
417 Integer major, Integer minor, String mode, String owner, String group, File targetDir);
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 @Override
442 public int hashCode() {
443 final int prime = 31;
444 int result = 1;
445 result = prime * result
446 + ((entryPath == null) ? 0 : entryPath.hashCode());
447 return result;
448 }
449
450 @Override
451 public boolean equals(Object obj) {
452 if (this == obj)
453 return true;
454 if (obj == null)
455 return false;
456 if (getClass() != obj.getClass())
457 return false;
458 final AbstractPrototypeEntry other = (AbstractPrototypeEntry) obj;
459 if (entryPath == null) {
460 if (other.entryPath != null)
461 return false;
462 } else if (!entryPath.equals(other.entryPath))
463 return false;
464 return true;
465 }
466
467 @Override
468 public String toString()
469 {
470 return this.getLine();
471 }
472
473 }