View | Details | Raw Unified | Return to bug 40184
Collapse All | Expand All

(-)src/main/org/apache/tools/ant/PropertyHelper.java (+141 lines)
Lines 18-23 Link Here
18
package org.apache.tools.ant;
18
package org.apache.tools.ant;
19
19
20
import java.util.Hashtable;
20
import java.util.Hashtable;
21
import java.util.Properties;
22
import java.util.Stack;
21
import java.util.Vector;
23
import java.util.Vector;
22
import java.util.Enumeration;
24
import java.util.Enumeration;
23
25
Lines 411-416 Link Here
411
        properties.put(name, value);
413
        properties.put(name, value);
412
    }
414
    }
413
415
416
    /**
417
     * Set a new inherited user property, which cannot be overwritten 
418
     * by set/unset property calls. If a user property with the
419
     * same name is already present the value is not overridden.
420
     * Also marks this property as a property that has not come 
421
     * from the command line.
422
     * 
423
     * @param ns The namespace for the property (currently not used).
424
     * @param n Name of property
425
     * @param v Value to set
426
     */
427
    public synchronized void setNewInheritedProperty(String ns, 
428
            String n, String v) {
429
        if (getUserProperty(null, n) == null) {
430
            setInheritedProperty(null, n, v);
431
        } else {
432
            project.log("Override ignored for " + n, Project.MSG_VERBOSE);
433
        }
434
    }
435
436
    /**
437
     * Adds a set of unexpanded properties.
438
     * <p>The properties are resolved, prefixed, expanded and added with 
439
     * {@link #setNewProperty(String, String, Object)}.</p>
440
     * @param props The unexpanded properties.
441
     * @param prefix The prefix to add to each property name
442
     *               after properties resolved.
443
     *               <code>null</code> if no prefix.
444
     */
445
    public synchronized void addNewProperties(String ns
446
            , Properties props, String prefix) {
447
        addUnexpandedProperties(ns, props, prefix, false);
448
    }
449
450
    /**
451
     * Adds a set of unexpanded inherited user properties.
452
     * <p>The properties are resolved, prefixed, expanded and added with 
453
     * {@link #setNewInheritedProperty(String, String, String)}.</p>
454
     * @param props The unexpanded inherited user properties.
455
     * @param prefix The prefix to add to each property name
456
     *               after properties resolved.
457
     *               <code>null</code> if no prefix.
458
     */
459
    public synchronized void addNewInheritedProperties(String ns
460
            , Properties props, String prefix) {
461
        addUnexpandedProperties(ns, props, prefix, true);
462
    }
463
464
    /**
465
     * Iterate through a set of properties,
466
     * resolve them then assign them
467
     * @param props The properties to iterate over.
468
     * @param prefix The prefix to add to each name.
469
     * @param userProperties Whether to be added as user properties.
470
     */
471
    private void addUnexpandedProperties(String ns
472
            , Properties props, String prefix, boolean userProperties) {
473
        resolveAllProperties(props);
474
        Enumeration e = props.keys();
475
        while (e.hasMoreElements()) {
476
            String propertyName = (String) e.nextElement();
477
            String propertyValue = props.getProperty(propertyName);
478
479
            String v = replaceProperties(null, propertyValue, null);
480
481
            if (prefix != null) {
482
                propertyName = prefix + propertyName;
483
            }
484
485
            if (userProperties) {
486
                setNewInheritedProperty(null, propertyName, v);
487
            } else {
488
                setNewProperty(null, propertyName, v);
489
            }
490
        }
491
    }
492
493
    /**
494
     * Resolve properties inside a properties hashtable
495
     * @param props Properties object to resolve
496
     */
497
    private void resolveAllProperties(Properties props) throws BuildException {
498
        for (Enumeration e = props.keys(); e.hasMoreElements();) {
499
            String propertyName = (String) e.nextElement();
500
            Stack referencesSeen = new Stack();
501
            resolve(props, propertyName, referencesSeen);
502
        }
503
    }
504
505
    /**
506
     * Recursively expand the named property using the project's
507
     * reference table and the given set of properties - fail if a
508
     * circular definition is detected.
509
     *
510
     * @param props Properties object to resolve
511
     * @param name Name of the property to resolve
512
     * @param referencesSeen Stack of all property names that have
513
     *                       been tried to expand before coming here.
514
     */
515
    private void resolve(Properties props, String name, Stack referencesSeen)
516
        throws BuildException {
517
        if (referencesSeen.contains(name)) {
518
            throw new BuildException("Property " + name + " was circularly "
519
                                     + "defined.");
520
        }
521
522
        String propertyValue = props.getProperty(name);
523
        Vector fragments = new Vector();
524
        Vector propertyRefs = new Vector();
525
        parsePropertyString(propertyValue, fragments, propertyRefs);
526
527
        if (propertyRefs.size() != 0) {
528
            referencesSeen.push(name);
529
            StringBuffer sb = new StringBuffer();
530
            Enumeration i = fragments.elements();
531
            Enumeration j = propertyRefs.elements();
532
            while (i.hasMoreElements()) {
533
                String fragment = (String) i.nextElement();
534
                if (fragment == null) {
535
                    String propertyName = (String) j.nextElement();
536
                    Object o = getProperty(null, propertyName);
537
                    fragment = (o == null) ? null : o.toString();
538
                    if (fragment == null) {
539
                        if (props.containsKey(propertyName)) {
540
                            resolve(props, propertyName, referencesSeen);
541
                            fragment = props.getProperty(propertyName);
542
                        } else {
543
                            fragment = "${" + propertyName + "}";
544
                        }
545
                    }
546
                }
547
                sb.append(fragment);
548
            }
549
            propertyValue = sb.toString();
550
            props.put(name, propertyValue);
551
            referencesSeen.pop();
552
        }
553
    }
554
414
    // -------------------- Getting properties  --------------------
555
    // -------------------- Getting properties  --------------------
415
556
416
    /**
557
    /**
(-)src/main/org/apache/tools/ant/taskdefs/Property.java (-85 / +12 lines)
Lines 24-30 Link Here
24
import java.net.URL;
24
import java.net.URL;
25
import java.util.Enumeration;
25
import java.util.Enumeration;
26
import java.util.Properties;
26
import java.util.Properties;
27
import java.util.Stack;
28
import java.util.Vector;
27
import java.util.Vector;
29
28
30
import org.apache.tools.ant.BuildException;
29
import org.apache.tools.ant.BuildException;
Lines 535-637 Link Here
535
    }
534
    }
536
535
537
    /**
536
    /**
538
     * iterate through a set of properties,
537
     * Add the properties to the property helper 
539
     * resolve them then assign them
538
     * @param props the properties to add
540
     * @param props the properties to iterate over
541
     */
539
     */
542
    protected void addProperties(Properties props) {
540
    protected void addProperties(Properties props) {
543
        resolveAllProperties(props);
541
        PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject());
544
        Enumeration e = props.keys();
542
        if (userProperty) {
545
        while (e.hasMoreElements()) {
543
            ph.addNewInheritedProperties(null, props, prefix);
546
            String propertyName = (String) e.nextElement();
544
        } else {
547
            String propertyValue = props.getProperty(propertyName);
545
            ph.addNewProperties(null, props, prefix);
548
549
            String v = getProject().replaceProperties(propertyValue);
550
551
            if (prefix != null) {
552
                propertyName = prefix + propertyName;
553
            }
554
555
            addProperty(propertyName, v);
556
        }
546
        }
557
    }
547
    }
558
548
559
    /**
549
    /**
560
     * add a name value pair to the project property set
550
     * Add a name value pair to the property helper
551
     * 
561
     * @param n name of property
552
     * @param n name of property
562
     * @param v value to set
553
     * @param v value to set
563
     */
554
     */
564
    protected void addProperty(String n, String v) {
555
    protected void addProperty(String n, String v) {
556
        PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject());
565
        if (userProperty) {
557
        if (userProperty) {
566
            if (getProject().getUserProperty(n) == null) {
558
            ph.setNewInheritedProperty(null, n, v);
567
                getProject().setInheritedProperty(n, v);
568
            } else {
569
                log("Override ignored for " + n, Project.MSG_VERBOSE);
570
            }
571
        } else {
559
        } else {
572
            getProject().setNewProperty(n, v);
560
            ph.setNewProperty(null, n, v);
573
        }
561
        }
574
    }
562
    }
575
563
576
    /**
577
     * resolve properties inside a properties hashtable
578
     * @param props properties object to resolve
579
     */
580
    private void resolveAllProperties(Properties props) throws BuildException {
581
        for (Enumeration e = props.keys(); e.hasMoreElements();) {
582
            String propertyName = (String) e.nextElement();
583
            Stack referencesSeen = new Stack();
584
            resolve(props, propertyName, referencesSeen);
585
        }
586
    }
587
588
    /**
589
     * Recursively expand the named property using the project's
590
     * reference table and the given set of properties - fail if a
591
     * circular definition is detected.
592
     *
593
     * @param props properties object to resolve
594
     * @param name of the property to resolve
595
     * @param referencesSeen stack of all property names that have
596
     * been tried to expand before coming here.
597
     */
598
    private void resolve(Properties props, String name, Stack referencesSeen)
599
        throws BuildException {
600
        if (referencesSeen.contains(name)) {
601
            throw new BuildException("Property " + name + " was circularly "
602
                                     + "defined.");
603
        }
604
605
        String propertyValue = props.getProperty(name);
606
        Vector fragments = new Vector();
607
        Vector propertyRefs = new Vector();
608
        PropertyHelper.getPropertyHelper(this.getProject()).parsePropertyString(propertyValue, fragments,
609
                propertyRefs);
610
611
        if (propertyRefs.size() != 0) {
612
            referencesSeen.push(name);
613
            StringBuffer sb = new StringBuffer();
614
            Enumeration i = fragments.elements();
615
            Enumeration j = propertyRefs.elements();
616
            while (i.hasMoreElements()) {
617
                String fragment = (String) i.nextElement();
618
                if (fragment == null) {
619
                    String propertyName = (String) j.nextElement();
620
                    fragment = getProject().getProperty(propertyName);
621
                    if (fragment == null) {
622
                        if (props.containsKey(propertyName)) {
623
                            resolve(props, propertyName, referencesSeen);
624
                            fragment = props.getProperty(propertyName);
625
                        } else {
626
                            fragment = "${" + propertyName + "}";
627
                        }
628
                    }
629
                }
630
                sb.append(fragment);
631
            }
632
            propertyValue = sb.toString();
633
            props.put(name, propertyValue);
634
            referencesSeen.pop();
635
        }
636
    }
637
}
564
}

Return to bug 40184