Source code: com/thermidor/build/tasks/RequiresTask.java
1 package com.thermidor.build.tasks;
2 import org.apache.tools.ant.*;
3 import org.apache.tools.ant.taskdefs.*;
4 import org.apache.tools.ant.types.*;
5 import java.io.*;
6 import java.util.*;
7 import gnu.regexp.*;
8 import java.util.zip.*;
9 import java.util.jar.*;
10 public class RequiresTask extends Task {
11 public static final String[] REGEX_SCAN_PATTERN={
12 "*.zip",
13 "**/*.zip",
14 "*.jar",
15 "**/*.jar",
16 "*.jlib",
17 "**/*.jlib"
18 };
19 public static final String[] LIB_SUFFIXES = {
20 ".zip",
21 ".jar",
22 ".jlib"
23 };
24 public abstract class Requirement {
25 protected String _pathProperty;
26 protected boolean _halt;
27 protected String _name;
28 public void setName(String name) {
29 _name = name;
30 }
31 public void setPathProperty(String pathProperty) {
32 _pathProperty = pathProperty;
33 }
34 public void setHalt(boolean halt) {
35 _halt = halt;
36 }
37 public abstract void execute();
38 }
39 public static final int AWK = 0;
40 public static final int ED = 1;
41 public static final int EGREP = 2;
42 public static final int EMACS = 3;
43 public static final int PERL4 = 4;
44 public static final int PERL4S = 5;
45 public static final int PERL5 = 6;
46 public static final int PERL5S = 7;
47 public static final int POSIX_AWK = 8;
48 public static final int POSIX_BASIC = 9;
49 public static final int POSIX_EXTENDED = 10;
50 public static final int POSIX_MINIMAL_BASIC = 11;
51 public static final int POSIX_MINIMAL_EXTENDED = 12;
52 public static final int SED = 13;
53 public static final String[] SYNTAXES = {
54 "awk",
55 "ed",
56 "egrep",
57 "emacs",
58 "grep",
59 "perl4",
60 "perl4s",
61 "perl5",
62 "perl5s",
63 "posix.awk",
64 "posix.basic",
65 "posix.extended",
66 "posix.minimal.basic",
67 "positx.minimal.extended",
68 "sed"
69 };
70 private static Hashtable SYNTAX_TABLE= new Hashtable();
71 static {
72 SYNTAX_TABLE.put(SYNTAXES[AWK],
73 RESyntax.RE_SYNTAX_AWK);
74 SYNTAX_TABLE.put(SYNTAXES[ED],
75 RESyntax.RE_SYNTAX_ED);
76 SYNTAX_TABLE.put(SYNTAXES[EGREP],
77 RESyntax.RE_SYNTAX_EGREP);
78 SYNTAX_TABLE.put(SYNTAXES[EMACS],
79 RESyntax.RE_SYNTAX_EMACS);
80 SYNTAX_TABLE.put(SYNTAXES[PERL4],
81 RESyntax.RE_SYNTAX_PERL4);
82 SYNTAX_TABLE.put(SYNTAXES[PERL4S],
83 RESyntax.RE_SYNTAX_PERL4_S);
84 SYNTAX_TABLE.put(SYNTAXES[PERL5]
85 ,RESyntax.RE_SYNTAX_PERL5);
86 SYNTAX_TABLE.put(SYNTAXES[PERL5S],
87 RESyntax.RE_SYNTAX_PERL5_S);
88 SYNTAX_TABLE.put(SYNTAXES[POSIX_AWK],
89 RESyntax.RE_SYNTAX_POSIX_AWK);
90 SYNTAX_TABLE.put(SYNTAXES[POSIX_BASIC],
91 RESyntax.RE_SYNTAX_POSIX_BASIC);
92 SYNTAX_TABLE.put(SYNTAXES[POSIX_EXTENDED],
93 RESyntax.RE_SYNTAX_POSIX_EXTENDED);
94 SYNTAX_TABLE.put(SYNTAXES[POSIX_MINIMAL_BASIC]
95 ,RESyntax.RE_SYNTAX_POSIX_MINIMAL_BASIC);
96 SYNTAX_TABLE.put(SYNTAXES[POSIX_MINIMAL_BASIC],
97 RESyntax.RE_SYNTAX_POSIX_MINIMAL_BASIC);
98 SYNTAX_TABLE.put(SYNTAXES[POSIX_MINIMAL_EXTENDED],
99 RESyntax.RE_SYNTAX_POSIX_MINIMAL_EXTENDED);
100 SYNTAX_TABLE.put(SYNTAXES[SED],
101 RESyntax.RE_SYNTAX_SED);
102 }
103 public static class Syntax extends EnumeratedAttribute {
104 public String[] getValues() {
105 return SYNTAXES;
106 }
107 }
108 public class RegexpRequirement extends Requirement {
109 private String _regexp;
110 private String _classpathref=null;
111 public void setRegexp(String regexp) {
112 _regexp = regexp;
113 }
114 private Syntax _syntax = new Syntax();
115 {
116 _syntax.setValue(SYNTAXES[EMACS]);
117 }
118 public void setSyntax(Syntax syntax) {
119 _syntax = syntax;
120 }
121 public void setClassPathRef(String classpathref){
122 _classpathref=classpathref;
123 }
124 private String libName(String fileName) {
125 String retval = fileName;
126 for(int cnt = 0; cnt < LIB_SUFFIXES.length; cnt++) {
127 String lcaseFile = fileName.toLowerCase();
128 String libSuf = LIB_SUFFIXES[cnt];
129 if (lcaseFile.endsWith(libSuf)) {
130 int pos = lcaseFile.lastIndexOf(libSuf);
131 retval = fileName.substring(0,pos-1);
132 break;
133 }
134 }
135 return retval;
136 }
137 public void execute() {
138 if(_name == null) {
139 _name = "unknown";
140 }
141 if(_classpathref == null) {
142 throw new BuildException("classpathref must be set");
143 }
144 RESyntax resyn = (RESyntax)SYNTAX_TABLE.get(_syntax.getValue());
145 log("searching for library matching '" + _regexp + "'");
146 RE regexp = null;
147 try {
148 regexp = new RE(_regexp,0,resyn);
149 }
150 catch(REException ree) {
151 throw new BuildException("invalid regular expression",ree);
152 }
153 String[] fs=_searchClassPath.list();
154 ArrayList files = new ArrayList();
155 ArrayList matchedLibs = new ArrayList();
156 int len = fs.length;
157 boolean found = false;
158 // try{
159 File find = null;
160 for(int cnt=0; cnt < len; cnt++) {
161 File tf=(new File(fs[cnt])).getAbsoluteFile();
162 if(tf.isDirectory()) {
163 DirectoryScanner ds = new DirectoryScanner();
164 ds.setBasedir(tf);
165 ds.setIncludes(REGEX_SCAN_PATTERN);
166 ds.scan();
167 String[] inFiles = ds.getIncludedFiles();
168 int length = inFiles.length;
169 for(int cnt2 = 0; cnt2 < length; cnt2 ++) {
170 find = new File(tf,inFiles[cnt2]).getAbsoluteFile();
171 String fileName = find.getName();
172 String libName=libName(fileName);
173 if (regexp.isMatch(libName)) {
174 found = true;
175 break;
176 }
177
178 }
179 }
180 }
181 if(found) {
182 log("found "+ find);
183 if(_pathProperty != null) {
184 getProject().setUserProperty(_pathProperty,"" + find);
185 }
186 else {
187 log("Regexp Lib Requiement: " + _name +
188 " path property not defined", Project.MSG_WARN);
189 }
190 Path classpath=(Path)getProject().getReferences().get(_classpathref);
191 classpath.setLocation(find);
192
193 }
194 else if (_halt) {
195 log("Regexp Lib Requiement: " + _name +" Failed") ;
196 throw new BuildException("could not find required files" +
197 _name);
198 }
199 // }
200 // catch(IOException ioe) {
201 // throw new BuildException("Regexp Lib Requiement error in "+ _name, ioe);
202 // }
203 }
204 }
205 public static class MatchType extends EnumeratedAttribute
206 {
207 public String[] getValues()
208 {
209 return new String[]{"exact","atleast"};
210 }
211 }
212 public static class ANComparator implements Comparator
213 {
214 public ANComparator() throws REException
215 {
216 tokenRE=new RE("\\([0-9]\\+\\)\\|\\([a-zA-Z._-]*\\)",0,RESyntax.RE_SYNTAX_SED);
217 }
218 public int compare(Object one,Object two)
219 {
220 if( one instanceof String && two instanceof String)
221 return anCompare((String)one,(String)two);
222 throw new ClassCastException();
223 }
224 private RE tokenRE=null;
225 private int anCompare(String name1,String name2)
226 {
227 REMatchEnumeration e1=tokenRE.getMatchEnumeration(name1);
228 REMatchEnumeration e2=tokenRE.getMatchEnumeration(name2);
229
230 while(e1.hasMoreElements()&&e2.hasMoreElements())
231 {
232 REMatch m1=e1.nextMatch();
233 REMatch m2=e2.nextMatch();
234 int test=0;
235 String m1s=m1.toString();
236 String m2s=m2.toString();
237 if(Character.isDigit(m1s.charAt(0)) && Character.isDigit(m2s.charAt(0) ) )
238 test=Integer.parseInt(m1s)-Integer.parseInt(m2s);
239 else
240 test=m1.toString().compareTo(m2.toString());
241 if(test!=0)
242 {
243 return test>0?1:-1;
244 }
245
246 }
247 if(!(e1.hasMoreElements() && e2.hasMoreElements()))
248 return 0;
249 else if((!e1.hasMoreElements()) && e2.hasMoreElements())
250 return -1;
251 return 1;
252
253 }
254 }
255 public class StandardRequirement extends Requirement {
256 private String _lib=null;
257 private RE _libRE=null;
258 private String _version=null;
259 private RE _versionRE=null;
260 private RE _libraryRE=null;
261 private MatchType _match=null;
262 private String _classpathref=null;
263 {
264 try
265 {
266 _libRE=new RE("^[a-zA-Z_]\\+\\([.-][a-zA-Z_]*\\)*",0,RESyntax.RE_SYNTAX_SED);
267 _versionRE=new RE("[0-9]\\+\\(\\.[0-9]\\+\\)*",0,RESyntax.RE_SYNTAX_SED);
268 _libraryRE=new RE("^\\([a-zA-Z_]\\+\\([.-][a-zA-Z_]*\\)*\\)-[0-9]\\+\\(\\.[0-9]\\+\\)*$",0,RESyntax.RE_SYNTAX_SED);
269 }
270 catch(REException re)
271 {
272 throw new BuildException(re.toString());
273 }
274 }
275 public void setLib(String lib)
276 {
277 _lib=lib;
278 }
279 public void setVersion(String version)
280 {
281 _version=version;
282 }
283 public void setMatch(MatchType match)
284 {
285 _match=match;
286 }
287 public void setClassPathRef(String classpathref)
288 {
289 _classpathref=classpathref;
290 }
291 public void execute()
292 {
293 String[] fs=_searchClassPath.list();
294 List files=new ArrayList();
295 String[] scanPattern={"**/"+_lib+"-*.jar","**/"+_lib+"-*.zip","**/"+_lib+"-*.jlib"};
296 List matchedLibs=new ArrayList();
297 boolean found=false;
298 String highestMatch=_version;
299 File highestMatchFile=null;
300 String exactMatch=null;
301 String matchedVersion="";
302 File exactMatchFile=null;
303 for(int cnt=0;cnt<fs.length;cnt++)
304 {
305 File tf=(new File(fs[cnt])).getAbsoluteFile();
306 if(tf.isDirectory())
307 {
308 DirectoryScanner ds=new DirectoryScanner();
309 ds.setBasedir(tf);
310 ds.setIncludes(scanPattern);
311 ds.scan();
312 String[] inFiles=ds.getIncludedFiles();
313 for(int cnt2=0;cnt2<inFiles.length;cnt2++)
314 {
315 matchedLibs.add((new File(tf,inFiles[cnt2])).getAbsoluteFile());
316 }
317 }
318 }
319 Iterator it=matchedLibs.iterator();
320 ANComparator com=null;
321 try
322 {
323 com=new ANComparator();
324 }
325 catch(REException e)
326 {
327 throw new BuildException("regexp failure in ANComparator");
328 }
329 while(it.hasNext())
330 {
331 File matchedFile=(File)it.next();
332 String matched=matchedFile.getName();
333 REMatch mlib=_libRE.getMatch(matched);
334 REMatch mversion=_versionRE.getMatch(matched);
335 if(_match.getValue().equals("exact"))
336 {
337 if(_version.equals(mversion.toString()))
338 {
339 found=true;
340 exactMatch=matched;
341 exactMatchFile=matchedFile;
342 matchedVersion=mversion.toString();
343 break;
344 }
345 }
346 else
347 {
348 int test=com.compare(mversion.toString(),_version);
349 if(test >=0)
350 {
351 found=true;
352 test=com.compare(matched,highestMatch);
353 if(test>=0)
354 {
355 highestMatch=matched;
356 highestMatchFile=matchedFile;
357 matchedVersion=mversion.toString();
358 }
359 }
360 }
361 }
362 File libFile=null;
363 if(found)
364 {
365 log("required library "+_lib+" version "+_version+" ... "+matchedVersion, Project.MSG_VERBOSE);
366 if(exactMatch!=null)
367 {
368 libFile=exactMatchFile;
369 }
370 else
371 {
372 libFile=highestMatchFile;
373 }
374 Path classpath=(Path)getProject().getReferences().get(_classpathref);
375 classpath.setLocation(libFile);
376 getProject().setUserProperty(_pathProperty,""+libFile);
377 }
378 else
379 {
380 log("required library "+_lib+" version "+_version+" ... no", Project.MSG_ERR);
381 //not found
382 if(_halt)
383 {
384 throw new BuildException("Halting build: Required lib "+_lib+" version "+_version+" not found");
385 }
386 }
387 }
388 }
389 public static final int SH = 0;
390 public static final int BASH = 1;
391 public static final int CSH = 2;
392 public static final int KSH = 3;
393 public static final int TCSH = 4;
394 public static final int CMD_EXE = 5;
395 public static final String[] SHELL_CMD = {
396 "sh",
397 "bash",
398 "csh",
399 "ksh",
400 "tcsh",
401 "cmd.exe"
402 };
403 private static class Shell {
404 private int _id;
405 private String _export;
406 private String[] _shellArgs;
407 public Shell(int id, String export, String[] shellArgs) {
408 _id = id;
409 _export = export;
410 _shellArgs = shellArgs;
411 }
412 public int getId() {
413 return _id;
414 }
415 public String getExport() {
416 return _export;
417 }
418 public String[] getShellArgs() {
419 return _shellArgs;
420 }
421 }
422 private static Hashtable SHELL_TABLE = new Hashtable();
423 static {
424 SHELL_TABLE.put(SHELL_CMD[SH], new Shell(SH,"export",new String[0]));
425 SHELL_TABLE.put(SHELL_CMD[BASH], new Shell(BASH,"export",new String[]{"-s"}));
426 SHELL_TABLE.put(SHELL_CMD[CSH], new Shell(CSH,"set",new String[]{"-s"}));
427 SHELL_TABLE.put(SHELL_CMD[KSH], new Shell(KSH,"export",new String[]{"-s"}));
428 SHELL_TABLE.put(SHELL_CMD[TCSH], new Shell(TCSH,"set",new String[]{"-s"}));
429 SHELL_TABLE.put(SHELL_CMD[CMD_EXE], new Shell(CMD_EXE,"set",new String[]{"/Q"}));
430 }
431 public static class ShellType extends EnumeratedAttribute
432 {
433 public String[] getValues()
434 {
435 return SHELL_CMD;
436 }
437 public String[] getShellArgs(String type)
438 {
439 return ((Shell)SHELL_TABLE.get(type)).getShellArgs();
440 }
441 }
442 public class IOHandler extends Thread
443 {
444 private final static int SIZE = 128;
445 private OutputStream _os=null;
446 private InputStream _is=null;
447 public IOHandler(InputStream is,OutputStream os)
448 {
449 super();
450 setDaemon(true);
451 _is=is;
452 _os=os;
453 }
454 public void begin()
455 {
456 start();
457 }
458 private final static int SLEEP = 5;
459 public void run()
460 {
461 try
462 {
463 log("IOHandler::run", Project.MSG_DEBUG);
464 byte[] data=new byte[SIZE];
465 int length;
466 while((length=_is.read(data))>0)
467 {
468 _os.write(data,0,length);
469 try {
470 Thread.sleep(SLEEP);
471 } catch (InterruptedException e) {}
472 }
473 }
474 catch(IOException ioe)
475 {
476 log(ioe.toString(), Project.MSG_ERR);
477 }
478 }
479 }
480 public class Export
481 {
482 public Export()
483 {
484 }
485 private String _name;
486 public String getName()
487 {
488 return _name;
489 }
490 public void setName(String name)
491 {
492 _name=name;
493 }
494 private String _value;
495 public String getValue()
496 {
497 return _value;
498 }
499 public void setValue(String value)
500 {
501 _value=value;
502 }
503
504 }
505 public class ScriptRequirement extends Requirement {
506 private List _exports=new ArrayList();
507 private ShellType _shellType;
508 private String _scriptText=null;
509 private boolean _echo;
510 public void setEcho(boolean echo) {
511 _echo = echo;
512 }
513 public Export createExport(){
514 Export retval = new Export();
515 _exports.add(retval);
516 return retval;
517 }
518 public void setShell(ShellType shellType) {
519 _shellType = shellType;
520 }
521 public void addText(String text)
522 {
523 _scriptText=text.trim();
524 if(_scriptText==null || (_scriptText!=null && _scriptText.length()==0))
525 {
526 log(" WARNING: body of script tag was empty", Project.MSG_WARN);
527 }
528 }
529 public void execute() throws BuildException
530 {
531 if(_name == null) {
532 _name = "unknown";
533 }
534 int success=0;
535 String shellValue = _shellType.getValue();
536 log("[Shellscript " +
537 shellValue +
538 "]" ,
539 Project.MSG_VERBOSE);
540
541 String exportList="";
542 Iterator it=_exports.iterator();
543 while(it.hasNext())
544 {
545 Export export=(Export)it.next();
546 String exportString=SHELL_TABLE.get(shellValue)+""+export.getName()+"=";
547 if(export.getValue()!=null)
548 {
549 exportString+=export.getValue()+"\n";
550 }
551 else
552 {
553 Project project=getProject();
554 String tmp=project.getProperty(export.getName());
555 if(tmp==null)
556 {
557 tmp=project.getUserProperty(export.getName());
558 if(tmp==null)
559 {
560 tmp="";
561 }
562 }
563 exportString+=tmp+"\n";
564 }
565 exportList+=exportString;
566 }
567
568 try
569 {
570 String shellType=(_shellType==null)?("sh"):(shellValue);
571 Process shell=Runtime.getRuntime().exec(shellValue,_shellType.getShellArgs(shellType));
572 DataOutputStream dos=new DataOutputStream(shell.getOutputStream());
573 byte[] exportBytes = exportList.getBytes();
574 dos.write(exportBytes);
575 if(_echo) {
576 System.out.write(exportBytes,0,exportBytes.length);
577 }
578 byte[] scriptBytes = _scriptText.getBytes();
579 dos.write(scriptBytes);
580 if(_echo) {
581 System.out.write(scriptBytes,0,scriptBytes.length);
582 }
583 dos.write((byte)0);
584 dos.flush();
585 dos.close();
586 ByteArrayOutputStream baos = new ByteArrayOutputStream();
587 IOHandler ioh1=new IOHandler(shell.getInputStream(),baos);
588 ioh1.start();
589 IOHandler ioh2=new IOHandler(shell.getErrorStream(),System.err);
590 ioh2.start();
591 success=shell.waitFor();
592 try
593 {
594 ioh1.join();
595 if(_echo) {
596 baos.writeTo(System.out);
597 if(_pathProperty != null) {
598 getProject().setUserProperty(_pathProperty,"" + baos.toString().trim());
599 }
600 else {
601 log("Script Requiement: " + _name +
602 " path property not defined", Project.MSG_WARN);
603 }
604 }
605 }
606 catch(Exception e2)
607 {
608 }
609 try
610 {
611 ioh2.join();
612 }
613 catch(Exception e2)
614 {
615 }
616 log(" ["+success+"]", Project.MSG_VERBOSE);
617 if(success != 0 && _halt) {
618 log("Script Requiement: " + _name + " failed");
619 throw new BuildException("Shellscript failed with code["+success+"]?");
620 }
621 }
622 catch(Exception ioe)
623 {
624 throw new BuildException("Shellscript failed with code["+success+"]?");
625 }
626 }
627 }
628 public abstract class FRElement {
629 protected File _file;
630 public abstract File exists();
631 }
632 public class ExeElement extends FRElement {
633 public void setFile(File file) {
634 _file = file;
635 }
636 public File exists() {
637 File retval=null;
638 log("checking for executable " + _file, Project.MSG_VERBOSE);
639 if(_file != null && !_file.isDirectory() && _file.exists()) {
640 retval = _file;
641 }
642 if(retval == null) {
643 String pathext = getProject().getUserProperty("system.PATHEXT");
644 if(pathext != null) {
645 StringTokenizer tokens= new StringTokenizer(pathext,";");
646 String pathName = _file.getPath();
647 String suf = null;
648 while(tokens.hasMoreTokens()) {
649 String tok = tokens.nextToken();
650 if(pathName.endsWith(tok)) {
651 continue;
652 }
653 suf = pathName + tok;
654 File tmp = new File(suf);
655 if(tmp != null &&
656 !tmp.isDirectory() &&
657 tmp.exists()) {
658 retval = tmp;
659 break;
660 }
661 }
662 }
663 }
664 return retval;
665 }
666 }
667 public class DirElement extends FRElement {
668 public void setDir(File file) {
669 _file = file;
670 }
671 public File exists() {
672 log("checking for " + _file, Project.MSG_VERBOSE);
673 if(_file != null && _file.isDirectory() && _file.exists()) {
674 return _file;
675 }
676 return null;
677 }
678 }
679 public class FileElement extends FRElement {
680 public void setFile(File file) {
681 _file = file;
682 }
683 public File exists() {
684 log("checking for " + _file, Project.MSG_VERBOSE);
685 if(_file != null && !_file.isDirectory() && _file.exists()) {
686 return _file;
687 }
688 return null;
689 }
690 }
691 public class FileRequirement extends Requirement {
692 private String _name;
693 private ArrayList _fileAlternatives = new ArrayList();
694 public FileElement createFile() {
695 FileElement retval = new FileElement();
696 _fileAlternatives.add(retval);
697 return retval;
698 }
699 public DirElement createDir() {
700 DirElement retval = new DirElement();
701 _fileAlternatives.add(retval);
702 return retval;
703 }
704 public ExeElement createExe() {
705 ExeElement retval = new ExeElement();
706 _fileAlternatives.add(retval);
707 return retval;
708 }
709 public void setName(String name) {
710 _name = name;
711 }
712 public void execute() {
713 File el = null;
714 if(_name == null) {
715 _name = "unknown";
716 }
717 boolean found = false;
718 try {
719 log("File Requiement: " + _name);
720 Iterator it = _fileAlternatives.iterator();
721 while(it.hasNext()) {
722 el = ((FRElement)it.next()).exists();
723 if (el != null) {
724 el = el.getCanonicalFile();
725 log("found "+ el);
726 if(_pathProperty != null) {
727 getProject().setUserProperty(_pathProperty,"" + el);
728 found = true;
729 break;
730 }
731 else {
732 log("File Requiement: " + _name +
733 " path property not defined", Project.MSG_WARN);
734 }
735 }
736
737 }
738 }
739 catch(IOException ioe) {
740 throw new BuildException("File Requirement error in "+ _name, ioe);
741 }
742 if (_halt && !found){
743 log("File Requiement: " + _name +" Failed") ;
744 throw new BuildException("could not find required files " +
745 _name);
746 }
747 }
748 }
749 public static final String MODULE_NAME =
750 "module.name";
751 public static final String MODULE_VERSION =
752 "module.version";
753 public static final String MODULE_BUILT_TIME =
754 "module.built.time";
755 public static final String MODULE_BUILT_OS_NAME =
756 "module.built.os.name";
757 public static final String MODULE_BUILT_OS_ARCH =
758 "module.built.os.arch";
759 public static final String MODULE_BUILT_OS_VERSION =
760 "module.built.os.version";
761 public static final String MODULE_BUILT_COMPILER =
762 "module.built.compiler";
763 public static final String MODULE_BUILT_JAVA_VERSION =
764 "module.built.java.version";
765 public static final String MODULE_BUILT_JAVA_VENDOR =
766 "module.built.java.vendor";
767 public static final String JLIB_INF_LOC =
768 "lib-inf/module.properties";
769 public class JlibRequirement extends Requirement {
770 private String _moduleName = null;
771 private String _moduleVersion = null;
772 private String _classpathref=null;
773 private RE _libRE=null;
774 private RE _versionRE=null;
775 private RE _libraryRE=null;
776 private MatchType _match=null;
777 {
778 try
779 {
780 _libRE=new RE("^[a-zA-Z_]\\+\\([.-][a-zA-Z_]*\\)*",0,RESyntax.RE_SYNTAX_SED);
781 _versionRE=new RE("[0-9]\\+\\(\\.[0-9]\\+\\)*",0,RESyntax.RE_SYNTAX_SED);
782 _libraryRE=new RE("^\\([a-zA-Z_]\\+\\([.-][a-zA-Z_]*\\)*\\)-[0-9]\\+\\(\\.[0-9]\\+\\)*$",0,RESyntax.RE_SYNTAX_SED);
783 }
784 catch(REException re)
785 {
786 throw new BuildException(re.toString());
787 }
788 }
789
790 public void setMatch(MatchType match)
791 {
792 _match=match;
793 }
794 public void setModuleName(String moduleName) {
795 _moduleName = moduleName;
796 }
797 public void setModuleVersion(String moduleVersion) {
798 _moduleVersion = moduleVersion;
799 }
800 public void setClassPathRef(String classpathref){
801 _classpathref=classpathref;
802 }
803 public void execute() {
804 try {
805 String[] fs=_searchClassPath.list();
806 List files=new ArrayList();
807 String[] scanPattern={"**/"+_moduleName+"-*.jlib",
808 "**/"+_moduleName+"-*.jar"};
809 List matchedLibs=new ArrayList();
810 boolean found=false;
811 String highestMatch=_moduleVersion;
812 File highestMatchFile=null;
813 String exactMatch=null;
814 String matchedVersion="";
815 File exactMatchFile=null;
816 for(int cnt=0;cnt<fs.length;cnt++)
817 {
818 File tf=(new File(fs[cnt])).getAbsoluteFile();
819 if(tf.isDirectory())
820 {
821 DirectoryScanner ds=new DirectoryScanner();
822 ds.setBasedir(tf);
823 ds.setIncludes(scanPattern);
824 ds.scan();
825 String[] inFiles=ds.getIncludedFiles();
826 for(int cnt2=0;cnt2<inFiles.length;cnt2++)
827 {
828 matchedLibs.add((new File(tf,inFiles[cnt2])).getAbsoluteFile());
829 }
830 }
831 }
832 Iterator it=matchedLibs.iterator();
833 // ANComparator com=null;
834 // try
835 // {
836 // com=new ANComparator();
837 // }
838 // catch(REException e)
839 // {
840 // throw new BuildException("regexp failure in ANComparator");
841 // }
842 while(it.hasNext())
843 {
844 File matchedFile=(File)it.next();
845 ZipFile jlibToTest = new ZipFile(matchedFile);
846 ZipEntry moduleEntry = jlibToTest.getEntry(JLIB_INF_LOC);
847 InputStream in = jlibToTest.getInputStream(moduleEntry);
848 Properties moduleProperties = new Properties();
849 moduleProperties.load(in);
850 in.close();
851 jlibToTest.close();
852
853
854
855
856
857 String matched=moduleProperties.getProperty(MODULE_NAME);
858 String ver=moduleProperties.getProperty(MODULE_VERSION);
859
860 if(!matched.equals(_moduleName)) {
861 log("found JLIB module with file name " +
862 matchedFile +
863 "but internal module name is " +
864 matched,Project.MSG_WARN);
865 }
866
867 REMatch mlib=_libRE.getMatch(matched);
868 REMatch mversion=_versionRE.getMatch(ver);
869 ANComparator com=null;
870 try
871 {
872 com=new ANComparator();
873 }
874 catch(REException e)
875 {
876 throw new BuildException("regexp failure in ANComparator");
877 }
878 if(_match.getValue().equals("exact"))
879 {
880 if(_moduleVersion.equals(mversion.toString()))
881 {
882 found=true;
883 exactMatch=matched;
884 exactMatchFile=matchedFile;
885 matchedVersion=mversion.toString();
886 break;
887 }
888 }
889 else
890 {
891 int test=com.compare(mversion.toString(),_moduleVersion);
892 if(test >=0)
893 {
894 found=true;
895 test=com.compare(matched,highestMatch);
896 if(test>=0)
897 {
898 highestMatch=matched;
899 highestMatchFile=matchedFile;
900 matchedVersion=mversion.toString();
901 }
902 }
903 }
904 }
905 File libFile=null;
906 if(found)
907 {
908 log("required library "+_moduleName+" version "+_moduleVersion+" ... "+matchedVersion, Project.MSG_VERBOSE);
909 if(exactMatch!=null)
910 {
911 libFile=exactMatchFile;
912 }
913 else
914 {
915 libFile=highestMatchFile;
916 }
917 Path classpath=(Path)getProject().getReferences().get(_classpathref);
918 classpath.setLocation(libFile);
919 System.out.println("JLIB classpath="+classpath);
920 getProject().setUserProperty(_pathProperty,""+libFile);
921 }
922 else
923 {
924 log("required library "+_moduleName+" version "+_moduleVersion+" ... no", Project.MSG_ERR);
925 //not found
926 if(_halt)
927 {
928 throw new BuildException("Halting build: Required lib "+_moduleName+" version "+_moduleVersion+" not found");
929 }
930 }
931 }
932 catch(IOException ioe) {
933 throw new BuildException("File Requirement error in "+ _name, ioe);
934 }
935 }
936 }
937 private Path _searchPath;
938 private Path _searchClassPath;
939 private ArrayList _regexpRequirements;
940 private ArrayList _standardRequirements;
941 private ArrayList _scriptRequirements;
942 private ArrayList _fileRequirements;
943 private ArrayList _jlibRequirements;
944 private ArrayList _requirements;
945
946 public RequiresTask() {
947 _regexpRequirements = new ArrayList();
948 _standardRequirements = new ArrayList();
949 _scriptRequirements = new ArrayList();
950 _fileRequirements = new ArrayList();
951 _jlibRequirements = new ArrayList();
952 _requirements = new ArrayList();
953 _requirements.add(_regexpRequirements);
954 _requirements.add(_standardRequirements);
955 _requirements.add(_scriptRequirements);
956 _requirements.add(_fileRequirements);
957 _requirements.add(_jlibRequirements);
958 }
959 public RegexpRequirement createRegexp() {
960 RegexpRequirement retval = new RegexpRequirement();
961 _regexpRequirements.add(retval);
962 return retval;
963 }
964 public StandardRequirement createStandard() {
965 StandardRequirement retval= new StandardRequirement();
966 _standardRequirements.add(retval);
967 return retval;
968 }
969 public ScriptRequirement createScript() {
970 ScriptRequirement retval = new ScriptRequirement();
971 _scriptRequirements.add(retval);
972 return retval;
973 }
974 public FileRequirement createFile() {
975 FileRequirement retval = new FileRequirement();
976 _fileRequirements.add(retval);
977 return retval;
978 }
979 public JlibRequirement createJLib() {
980 JlibRequirement retval = new JlibRequirement();
981 _jlibRequirements.add(retval);
982 return retval;
983 }
984 public Path createSearchPath() {
985 if(_searchPath == null) {
986 _searchPath = new Path(getProject());
987 }
988 return _searchPath;
989 }
990 public Path createSearchClassPath() {
991 if(_searchClassPath == null) {
992 _searchClassPath = new Path(getProject());
993 }
994 return _searchClassPath;
995 }
996 public void execute() {
997 System.out.println("project="+getProject());
998 Property system = (Property)getProject().createTask("property");
999 system.setEnvironment("system");
1000 system.execute();
1001 Iterator it = _requirements.iterator();
1002 while(it.hasNext()) {
1003 Iterator reqIt = ((ArrayList)it.next()).iterator();
1004 while(reqIt.hasNext()) {
1005 ((Requirement)reqIt.next()).execute();
1006 }
1007 }
1008 }
1009}