Source Code Cross Referenced for Symlink.java in  » Build » ANT » org » apache » tools » ant » taskdefs » optional » unix » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Build » ANT » org.apache.tools.ant.taskdefs.optional.unix 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         *
017:         */
018:
019:        /*
020:         * Since the initial version of this file was developed on the clock on
021:         * an NSF grant I should say the following boilerplate:
022:         *
023:         * This material is based upon work supported by the National Science
024:         * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and
025:         * conclusions or recommendations expressed in this material are those
026:         * of the author and do not necessarily reflect the views of the
027:         * National Science Foundation.
028:         */
029:
030:        package org.apache.tools.ant.taskdefs.optional.unix;
031:
032:        import java.io.File;
033:        import java.io.IOException;
034:        import java.io.PrintStream;
035:        import java.io.FileInputStream;
036:        import java.io.FileOutputStream;
037:        import java.io.BufferedInputStream;
038:        import java.io.BufferedOutputStream;
039:        import java.io.FileNotFoundException;
040:
041:        import java.util.Vector;
042:        import java.util.HashSet;
043:        import java.util.Iterator;
044:        import java.util.Hashtable;
045:        import java.util.Properties;
046:
047:        import org.apache.tools.ant.Project;
048:        import org.apache.tools.ant.BuildException;
049:        import org.apache.tools.ant.DirectoryScanner;
050:        import org.apache.tools.ant.dispatch.DispatchTask;
051:        import org.apache.tools.ant.dispatch.DispatchUtils;
052:        import org.apache.tools.ant.taskdefs.Execute;
053:        import org.apache.tools.ant.taskdefs.LogOutputStream;
054:        import org.apache.tools.ant.types.FileSet;
055:        import org.apache.tools.ant.types.Commandline;
056:        import org.apache.tools.ant.util.FileUtils;
057:
058:        /**
059:         * Creates, Deletes, Records and Restores Symlinks.
060:         *
061:         * <p> This task performs several related operations. In the most trivial
062:         * and default usage, it creates a link specified in the link attribute to
063:         * a resource specified in the resource attribute. The second usage of this
064:         * task is to traverse a directory structure specified by a fileset,
065:         * and write a properties file in each included directory describing the
066:         * links found in that directory. The third usage is to traverse a
067:         * directory structure specified by a fileset, looking for properties files
068:         * (also specified as included in the fileset) and recreate the links
069:         * that have been previously recorded for each directory. Finally, it can be
070:         * used to remove a symlink without deleting the associated resource.
071:         *
072:         * <p> Usage examples:
073:         *
074:         * <p> Make a link named &quot;foo&quot; to a resource named
075:         * &quot;bar.foo&quot; in subdir:
076:         * <pre>
077:         * &lt;symlink link=&quot;${dir.top}/foo&quot; resource=&quot;${dir.top}/subdir/bar.foo&quot;/&gt;
078:         * </pre>
079:         *
080:         * <p> Record all links in subdir and its descendants in files named
081:         * &quot;dir.links&quot;:
082:         * <pre>
083:         * &lt;symlink action=&quot;record&quot; linkfilename=&quot;dir.links&quot;&gt;
084:         *    &lt;fileset dir=&quot;${dir.top}&quot; includes=&quot;subdir&#47;**&quot; /&gt;
085:         * &lt;/symlink&gt;
086:         * </pre>
087:         *
088:         * <p> Recreate the links recorded in the previous example:
089:         * <pre>
090:         * &lt;symlink action=&quot;recreate&quot;&gt;
091:         *    &lt;fileset dir=&quot;${dir.top}&quot; includes=&quot;subdir&#47;**&#47;dir.links&quot; /&gt;
092:         * &lt;/symlink&gt;
093:         * </pre>
094:         *
095:         * <p> Delete a link named &quot;foo&quot; to a resource named
096:         * &quot;bar.foo&quot; in subdir:
097:         * <pre>
098:         * &lt;symlink action=&quot;delete&quot; link=&quot;${dir.top}/foo&quot;/&gt;
099:         * </pre>
100:         *
101:         * <p><strong>LIMITATIONS:</strong> Because Java has no direct support for
102:         * handling symlinks this task divines them by comparing canonical and
103:         * absolute paths. On non-unix systems this may cause false positives.
104:         * Furthermore, any operating system on which the command
105:         * <code>ln -s link resource</code> is not a valid command on the command line
106:         * will not be able to use action=&quot;delete&quot;, action=&quot;single&quot;
107:         * or action=&quot;recreate&quot;, but action=&quot;record&quot; should still
108:         * work. Finally, the lack of support for symlinks in Java means that all links
109:         * are recorded as links to the <strong>canonical</strong> resource name.
110:         * Therefore the link: <code>link --> subdir/dir/../foo.bar</code> will be
111:         * recorded as <code>link=subdir/foo.bar</code> and restored as
112:         * <code>link --> subdir/foo.bar</code>.
113:         *
114:         */
115:        public class Symlink extends DispatchTask {
116:            private static final FileUtils FILE_UTILS = FileUtils
117:                    .getFileUtils();
118:
119:            private String resource;
120:            private String link;
121:            private Vector fileSets = new Vector();
122:            private String linkFileName;
123:            private boolean overwrite;
124:            private boolean failonerror;
125:            private boolean executing = false;
126:
127:            /**
128:             * Initialize the task.
129:             * @throws BuildException on error.
130:             */
131:            public void init() throws BuildException {
132:                super .init();
133:                setDefaults();
134:            }
135:
136:            /**
137:             * The standard method for executing any task.
138:             * @throws BuildException on error.
139:             */
140:            public synchronized void execute() throws BuildException {
141:                if (executing) {
142:                    throw new BuildException(
143:                            "Infinite recursion detected in Symlink.execute()");
144:                }
145:                try {
146:                    executing = true;
147:                    DispatchUtils.execute(this );
148:                } finally {
149:                    executing = false;
150:                }
151:            }
152:
153:            /**
154:             * Create a symlink.
155:             * @throws BuildException on error.
156:             * @since Ant 1.7
157:             */
158:            public void single() throws BuildException {
159:                try {
160:                    if (resource == null) {
161:                        handleError("Must define the resource to symlink to!");
162:                        return;
163:                    }
164:                    if (link == null) {
165:                        handleError("Must define the link name for symlink!");
166:                        return;
167:                    }
168:                    doLink(resource, link);
169:                } finally {
170:                    setDefaults();
171:                }
172:            }
173:
174:            /**
175:             * Delete a symlink.
176:             * @throws BuildException on error.
177:             * @since Ant 1.7
178:             */
179:            public void delete() throws BuildException {
180:                try {
181:                    if (link == null) {
182:                        handleError("Must define the link name for symlink!");
183:                        return;
184:                    }
185:                    log("Removing symlink: " + link);
186:                    deleteSymlink(link);
187:                } catch (FileNotFoundException fnfe) {
188:                    handleError(fnfe.toString());
189:                } catch (IOException ioe) {
190:                    handleError(ioe.toString());
191:                } finally {
192:                    setDefaults();
193:                }
194:            }
195:
196:            /**
197:             * Restore symlinks.
198:             * @throws BuildException on error.
199:             * @since Ant 1.7
200:             */
201:            public void recreate() throws BuildException {
202:                try {
203:                    if (fileSets.isEmpty()) {
204:                        handleError("File set identifying link file(s) "
205:                                + "required for action recreate");
206:                        return;
207:                    }
208:                    Properties links = loadLinks(fileSets);
209:
210:                    for (Iterator kitr = links.keySet().iterator(); kitr
211:                            .hasNext();) {
212:                        String lnk = (String) kitr.next();
213:                        String res = links.getProperty(lnk);
214:                        // handle the case where lnk points to a directory (bug 25181)
215:                        try {
216:                            File test = new File(lnk);
217:                            if (!FILE_UTILS.isSymbolicLink(null, lnk)) {
218:                                doLink(res, lnk);
219:                            } else if (!test.getCanonicalPath().equals(
220:                                    new File(res).getCanonicalPath())) {
221:                                deleteSymlink(lnk);
222:                                doLink(res, lnk);
223:                            } // else lnk exists, do nothing
224:                        } catch (IOException ioe) {
225:                            handleError("IO exception while creating link");
226:                        }
227:                    }
228:                } finally {
229:                    setDefaults();
230:                }
231:            }
232:
233:            /**
234:             * Record symlinks.
235:             * @throws BuildException on error.
236:             * @since Ant 1.7
237:             */
238:            public void record() throws BuildException {
239:                try {
240:                    if (fileSets.isEmpty()) {
241:                        handleError("Fileset identifying links to record required");
242:                        return;
243:                    }
244:                    if (linkFileName == null) {
245:                        handleError("Name of file to record links in required");
246:                        return;
247:                    }
248:                    // create a hashtable to group them by parent directory:
249:                    Hashtable byDir = new Hashtable();
250:
251:                    // get an Iterator of file objects representing links (canonical):
252:                    for (Iterator litr = findLinks(fileSets).iterator(); litr
253:                            .hasNext();) {
254:                        File this Link = (File) litr.next();
255:                        File parent = this Link.getParentFile();
256:                        Vector v = (Vector) byDir.get(parent);
257:                        if (v == null) {
258:                            v = new Vector();
259:                            byDir.put(parent, v);
260:                        }
261:                        v.addElement(this Link);
262:                    }
263:                    // write a Properties file in each directory:
264:                    for (Iterator dirs = byDir.keySet().iterator(); dirs
265:                            .hasNext();) {
266:                        File dir = (File) dirs.next();
267:                        Vector linksInDir = (Vector) byDir.get(dir);
268:                        Properties linksToStore = new Properties();
269:
270:                        // fill up a Properties object with link and resource names:
271:                        for (Iterator dlnk = linksInDir.iterator(); dlnk
272:                                .hasNext();) {
273:                            File lnk = (File) dlnk.next();
274:                            try {
275:                                linksToStore.put(lnk.getName(), lnk
276:                                        .getCanonicalPath());
277:                            } catch (IOException ioe) {
278:                                handleError("Couldn't get canonical name of parent link");
279:                            }
280:                        }
281:                        writePropertyFile(linksToStore, dir);
282:                    }
283:                } finally {
284:                    setDefaults();
285:                }
286:            }
287:
288:            /**
289:             * Return all variables to their default state for the next invocation.
290:             * @since Ant 1.7
291:             */
292:            private void setDefaults() {
293:                resource = null;
294:                link = null;
295:                linkFileName = null;
296:                failonerror = true; // default behavior is to fail on an error
297:                overwrite = false; // default behavior is to not overwrite
298:                setAction("single"); // default behavior is make a single link
299:                fileSets.clear();
300:            }
301:
302:            /**
303:             * Set overwrite mode. If set to false (default)
304:             * the task will not overwrite existing links, and may stop the build
305:             * if a link already exists depending on the setting of failonerror.
306:             *
307:             * @param owrite If true overwrite existing links.
308:             */
309:            public void setOverwrite(boolean owrite) {
310:                this .overwrite = owrite;
311:            }
312:
313:            /**
314:             * Set failonerror mode. If set to true (default) the entire build fails
315:             * upon error; otherwise the error is logged and the build will continue.
316:             *
317:             * @param foe    If true throw BuildException on error, else log it.
318:             */
319:            public void setFailOnError(boolean foe) {
320:                this .failonerror = foe;
321:            }
322:
323:            /**
324:             * Set the action to be performed.  May be &quot;single&quot;,
325:             * &quot;delete&quot;, &quot;recreate&quot; or &quot;record&quot;.
326:             *
327:             * @param action    The action to perform.
328:             */
329:            public void setAction(String action) {
330:                super .setAction(action);
331:            }
332:
333:            /**
334:             * Set the name of the link. Used when action = &quot;single&quot;.
335:             *
336:             * @param lnk     The name for the link.
337:             */
338:            public void setLink(String lnk) {
339:                this .link = lnk;
340:            }
341:
342:            /**
343:             * Set the name of the resource to which a link should be created.
344:             * Used when action = &quot;single&quot;.
345:             *
346:             * @param src      The resource to be linked.
347:             */
348:            public void setResource(String src) {
349:                this .resource = src;
350:            }
351:
352:            /**
353:             * Set the name of the file to which links will be written.
354:             * Used when action = &quot;record&quot;.
355:             *
356:             * @param lf      The name of the file to write links to.
357:             */
358:            public void setLinkfilename(String lf) {
359:                this .linkFileName = lf;
360:            }
361:
362:            /**
363:             * Add a fileset to this task.
364:             *
365:             * @param set      The fileset to add.
366:             */
367:            public void addFileset(FileSet set) {
368:                fileSets.addElement(set);
369:            }
370:
371:            /**
372:             * Delete a symlink (without deleting the associated resource).
373:             *
374:             * <p>This is a convenience method that simply invokes
375:             * <code>deleteSymlink(java.io.File)</code>.
376:             *
377:             * @param path    A string containing the path of the symlink to delete.
378:             *
379:             * @throws FileNotFoundException   When the path results in a
380:             *                                   <code>File</code> that doesn't exist.
381:             * @throws IOException             If calls to <code>File.rename</code>
382:             *                                   or <code>File.delete</code> fail.
383:             */
384:            public static void deleteSymlink(String path) throws IOException,
385:                    FileNotFoundException {
386:                deleteSymlink(new File(path));
387:            }
388:
389:            /**
390:             * Delete a symlink (without deleting the associated resource).
391:             *
392:             * <p>This is a utility method that removes a unix symlink without removing
393:             * the resource that the symlink points to. If it is accidentally invoked
394:             * on a real file, the real file will not be harmed, but an exception
395:             * will be thrown when the deletion is attempted. This method works by
396:             * getting the canonical path of the link, using the canonical path to
397:             * rename the resource (breaking the link) and then deleting the link.
398:             * The resource is then returned to its original name inside a finally
399:             * block to ensure that the resource is unharmed even in the event of
400:             * an exception.
401:             *
402:             * @param linkfil    A <code>File</code> object of the symlink to delete.
403:             *
404:             * @throws FileNotFoundException   When the path results in a
405:             *                                   <code>File</code> that doesn't exist.
406:             * @throws IOException             If calls to <code>File.rename</code>,
407:             *                                   <code>File.delete</code> or
408:             *                                   <code>File.getCanonicalPath</code>
409:             *                                   fail.
410:             */
411:            public static void deleteSymlink(File linkfil) throws IOException,
412:                    FileNotFoundException {
413:                if (!linkfil.exists()) {
414:                    throw new FileNotFoundException("No such symlink: "
415:                            + linkfil);
416:                }
417:                // find the resource of the existing link:
418:                File canfil = linkfil.getCanonicalFile();
419:
420:                // rename the resource, thus breaking the link:
421:                File temp = FILE_UTILS.createTempFile("symlink", ".tmp", canfil
422:                        .getParentFile());
423:                try {
424:                    try {
425:                        FILE_UTILS.rename(canfil, temp);
426:                    } catch (IOException e) {
427:                        throw new IOException(
428:                                "Couldn't rename resource when attempting to delete "
429:                                        + linkfil);
430:                    }
431:                    // delete the (now) broken link:
432:                    if (!linkfil.delete()) {
433:                        throw new IOException(
434:                                "Couldn't delete symlink: "
435:                                        + linkfil
436:                                        + " (was it a real file? is this not a UNIX system?)");
437:                    }
438:                } finally {
439:                    // return the resource to its original name:
440:                    try {
441:                        FILE_UTILS.rename(temp, canfil);
442:                    } catch (IOException e) {
443:                        throw new IOException("Couldn't return resource "
444:                                + temp + " to its original name: "
445:                                + canfil.getAbsolutePath()
446:                                + "\n THE RESOURCE'S NAME ON DISK HAS "
447:                                + "BEEN CHANGED BY THIS ERROR!\n");
448:                    }
449:                }
450:            }
451:
452:            /**
453:             * Write a properties file. This method uses <code>Properties.store</code>
454:             * and thus may throw exceptions that occur while writing the file.
455:             *
456:             * @param properties     The properties object to be written.
457:             * @param dir            The directory for which we are writing the links.
458:             */
459:            private void writePropertyFile(Properties properties, File dir)
460:                    throws BuildException {
461:                BufferedOutputStream bos = null;
462:                try {
463:                    bos = new BufferedOutputStream(new FileOutputStream(
464:                            new File(dir, linkFileName)));
465:                    properties.store(bos, "Symlinks from " + dir);
466:                } catch (IOException ioe) {
467:                    throw new BuildException(ioe, getLocation());
468:                } finally {
469:                    FileUtils.close(bos);
470:                }
471:            }
472:
473:            /**
474:             * Handle errors based on the setting of failonerror.
475:             *
476:             * @param msg    The message to log, or include in the
477:             *                  <code>BuildException</code>.
478:             */
479:            private void handleError(String msg) {
480:                if (failonerror) {
481:                    throw new BuildException(msg);
482:                }
483:                log(msg);
484:            }
485:
486:            /**
487:             * Conduct the actual construction of a link.
488:             *
489:             * <p> The link is constructed by calling <code>Execute.runCommand</code>.
490:             *
491:             * @param res   The path of the resource we are linking to.
492:             * @param lnk       The name of the link we wish to make.
493:             */
494:            private void doLink(String res, String lnk) throws BuildException {
495:                File linkfil = new File(lnk);
496:                if (overwrite && linkfil.exists()) {
497:                    try {
498:                        deleteSymlink(linkfil);
499:                    } catch (FileNotFoundException fnfe) {
500:                        handleError("Symlink disappeared before it was deleted: "
501:                                + lnk);
502:                    } catch (IOException ioe) {
503:                        handleError("Unable to overwrite preexisting link: "
504:                                + lnk);
505:                    }
506:                }
507:                String[] cmd = new String[] { "ln", "-s", res, lnk };
508:                log(Commandline.toString(cmd));
509:                Execute.runCommand(this , cmd);
510:            }
511:
512:            /**
513:             * Find all the links in all supplied filesets.
514:             *
515:             * <p> This method is invoked when the action attribute is
516:             * &quot;record&quot;. This means that filesets are interpreted
517:             * as the directories in which links may be found.
518:             *
519:             * @param v   The filesets specified by the user.
520:             * @return A HashSet of <code>File</code> objects containing the
521:             *         links (with canonical parent directories).
522:             */
523:            private HashSet findLinks(Vector v) {
524:                HashSet result = new HashSet();
525:                for (int i = 0; i < v.size(); i++) {
526:                    FileSet fs = (FileSet) v.get(i);
527:                    DirectoryScanner ds = fs.getDirectoryScanner(getProject());
528:                    String[][] fnd = new String[][] { ds.getIncludedFiles(),
529:                            ds.getIncludedDirectories() };
530:                    File dir = fs.getDir(getProject());
531:                    for (int j = 0; j < fnd.length; j++) {
532:                        for (int k = 0; k < fnd[j].length; k++) {
533:                            try {
534:                                File f = new File(dir, fnd[j][k]);
535:                                File pf = f.getParentFile();
536:                                String name = f.getName();
537:                                if (FILE_UTILS.isSymbolicLink(pf, name)) {
538:                                    result.add(new File(pf.getCanonicalFile(),
539:                                            name));
540:                                }
541:                            } catch (IOException e) {
542:                                handleError("IOException: " + fnd[j][k]
543:                                        + " omitted");
544:                            }
545:                        }
546:                    }
547:                }
548:                return result;
549:            }
550:
551:            /**
552:             * Load links from properties files included in one or more FileSets.
553:             *
554:             * <p> This method is only invoked when the action attribute is set to
555:             * &quot;recreate&quot;. The filesets passed in are assumed to specify the
556:             * names of the property files with the link information and the
557:             * subdirectories in which to look for them.
558:             *
559:             * @param v    The <code>FileSet</code>s for this task.
560:             * @return            The links to be made.
561:             */
562:            private Properties loadLinks(Vector v) {
563:                Properties finalList = new Properties();
564:                // loop through the supplied file sets:
565:                for (int i = 0; i < v.size(); i++) {
566:                    FileSet fs = (FileSet) v.elementAt(i);
567:                    DirectoryScanner ds = new DirectoryScanner();
568:                    fs.setupDirectoryScanner(ds, getProject());
569:                    ds.setFollowSymlinks(false);
570:                    ds.scan();
571:                    String[] incs = ds.getIncludedFiles();
572:                    File dir = fs.getDir(getProject());
573:
574:                    // load included files as properties files:
575:                    for (int j = 0; j < incs.length; j++) {
576:                        File inc = new File(dir, incs[j]);
577:                        File pf = inc.getParentFile();
578:                        Properties lnks = new Properties();
579:                        try {
580:                            lnks.load(new BufferedInputStream(
581:                                    new FileInputStream(inc)));
582:                            pf = pf.getCanonicalFile();
583:                        } catch (FileNotFoundException fnfe) {
584:                            handleError("Unable to find " + incs[j]
585:                                    + "; skipping it.");
586:                            continue;
587:                        } catch (IOException ioe) {
588:                            handleError("Unable to open " + incs[j]
589:                                    + " or its parent dir; skipping it.");
590:                            continue;
591:                        }
592:                        lnks.list(new PrintStream(new LogOutputStream(this ,
593:                                Project.MSG_INFO)));
594:                        // Write the contents to our master list of links
595:                        // This method assumes that all links are defined in
596:                        // terms of absolute paths, or paths relative to the
597:                        // working directory:
598:                        for (Iterator kitr = lnks.keySet().iterator(); kitr
599:                                .hasNext();) {
600:                            String key = (String) kitr.next();
601:                            finalList.put(new File(pf, key).getAbsolutePath(),
602:                                    lnks.getProperty(key));
603:                        }
604:                    }
605:                }
606:                return finalList;
607:            }
608:        }
www__._j_a__v_a___2__s___._c__o___m___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.