Lines 32-37
Link Here
|
32 |
import org.openide.modules.InstalledFileLocator; |
32 |
import org.openide.modules.InstalledFileLocator; |
33 |
import org.openide.modules.ModuleInfo; |
33 |
import org.openide.modules.ModuleInfo; |
34 |
import org.openide.util.*; |
34 |
import org.openide.util.*; |
|
|
35 |
import org.openide.util.io.NullOutputStream; |
35 |
import org.openide.xml.XMLUtil; |
36 |
import org.openide.xml.XMLUtil; |
36 |
import org.w3c.dom.Document; |
37 |
import org.w3c.dom.Document; |
37 |
import org.w3c.dom.Element; |
38 |
import org.w3c.dom.Element; |
Lines 504-551
Link Here
|
504 |
|
505 |
|
505 |
} |
506 |
} |
506 |
|
507 |
|
507 |
// XXX better would be to multiplex to the currently running Ant process, as |
508 |
// I/O redirection impl. Keyed by thread group (each Ant process has its own TG). |
508 |
// determined by the current thread group |
509 |
// Various Ant tasks (e.g. <java fork="false" output="..." ...>) need the system |
509 |
// Better still would be to let the execution engine handle it entirely, |
510 |
// I/O streams to be redirected to the demux streams of the project so they can |
510 |
// by creating a custom InputOutput: #1961 |
511 |
// be handled properly. Ideally nothing would try to read directly from stdin |
511 |
|
512 |
// or print directly to stdout/stderr but in fact some tasks do. |
|
|
513 |
// Could also pass a custom InputOutput to ExecutionEngine, perhaps, but this |
514 |
// seems a lot simpler and probably has the same effect. |
515 |
|
516 |
private static int delegating = 0; |
512 |
private static InputStream origIn; |
517 |
private static InputStream origIn; |
513 |
private static PrintStream origOut, origErr; |
518 |
private static PrintStream origOut, origErr; |
|
|
519 |
private static Map/*<ThreadGroup,InputStream>*/ delegateIns = new HashMap(); |
520 |
private static Map/*<ThreadGroup,PrintStream>*/ delegateOuts = new HashMap(); |
521 |
private static Map/*<ThreadGroup,PrintStream>*/ delegateErrs = new HashMap(); |
514 |
|
522 |
|
515 |
/** |
523 |
/** |
516 |
* Handle I/O scoping for overlapping project runs. |
524 |
* Handle I/O scoping for overlapping project runs. |
517 |
* You must call {@link #restoreSystemInOutErr} in a finally block. |
525 |
* You must call {@link #restoreSystemInOutErr} in a finally block. |
518 |
* @param out new temporary output stream for the VM |
526 |
* @param in new temporary input stream for this thread group |
519 |
* @param err new temporary error stream for the VM |
527 |
* @param out new temporary output stream for this thread group |
|
|
528 |
* @param err new temporary error stream for this thread group |
520 |
* @see "#36396" |
529 |
* @see "#36396" |
521 |
*/ |
530 |
*/ |
522 |
public static synchronized void pushSystemInOutErr(InputStream in, PrintStream out, PrintStream err) { |
531 |
public static synchronized void pushSystemInOutErr(InputStream in, PrintStream out, PrintStream err) { |
523 |
if (origOut == null) { |
532 |
if (delegating++ == 0) { |
524 |
origIn = System.in; |
533 |
origIn = System.in; |
525 |
origOut = System.out; |
534 |
origOut = System.out; |
526 |
origErr = System.err; |
535 |
origErr = System.err; |
527 |
} else { |
536 |
System.setIn(new MultiplexInputStream()); |
528 |
// Oh well, old output may be sent to the wrong window... |
537 |
System.setOut(new MultiplexPrintStream(false)); |
529 |
} |
538 |
System.setErr(new MultiplexPrintStream(true)); |
530 |
System.setIn(in); |
539 |
} |
531 |
System.setOut(out); |
540 |
ThreadGroup tg = Thread.currentThread().getThreadGroup(); |
532 |
System.setErr(err); |
541 |
delegateIns.put(tg, in); |
|
|
542 |
delegateOuts.put(tg, out); |
543 |
delegateErrs.put(tg, err); |
533 |
} |
544 |
} |
534 |
|
545 |
|
535 |
/** |
546 |
/** |
536 |
* Restore original I/O streams after a call to {@link #pushSystemInOutErr}. |
547 |
* Restore original I/O streams after a call to {@link #pushSystemInOutErr}. |
537 |
*/ |
548 |
*/ |
538 |
public static synchronized void restoreSystemInOutErr() { |
549 |
public static synchronized void restoreSystemInOutErr() { |
539 |
if (origOut != null) { |
550 |
assert delegating > 0; |
|
|
551 |
if (--delegating == 0) { |
540 |
System.setIn(origIn); |
552 |
System.setIn(origIn); |
541 |
System.setErr(origErr); |
|
|
542 |
System.setOut(origOut); |
553 |
System.setOut(origOut); |
|
|
554 |
System.setErr(origErr); |
543 |
origIn = null; |
555 |
origIn = null; |
544 |
origOut = null; |
556 |
origOut = null; |
545 |
origErr = null; |
557 |
origErr = null; |
546 |
} else { |
|
|
547 |
// Again, never mind. |
548 |
} |
558 |
} |
|
|
559 |
ThreadGroup tg = Thread.currentThread().getThreadGroup(); |
560 |
delegateIns.remove(tg); |
561 |
delegateOuts.remove(tg); |
562 |
delegateErrs.remove(tg); |
563 |
} |
564 |
|
565 |
private static final class MultiplexInputStream extends InputStream { |
566 |
|
567 |
public MultiplexInputStream() {} |
568 |
|
569 |
private InputStream delegate() { |
570 |
ThreadGroup tg = Thread.currentThread().getThreadGroup(); |
571 |
while (tg != null && !delegateIns.containsKey(tg)) { |
572 |
tg = tg.getParent(); |
573 |
} |
574 |
InputStream is = (InputStream)delegateIns.get(tg); |
575 |
if (is != null) { |
576 |
return is; |
577 |
} else if (delegating > 0) { |
578 |
assert origIn != null; |
579 |
return origIn; |
580 |
} else { |
581 |
// Probably should not happen? But not sure. |
582 |
return System.in; |
583 |
} |
584 |
} |
585 |
|
586 |
public int read() throws IOException { |
587 |
return delegate().read(); |
588 |
} |
589 |
|
590 |
public int read(byte[] b) throws IOException { |
591 |
return delegate().read(b); |
592 |
} |
593 |
|
594 |
public int read(byte[] b, int off, int len) throws IOException { |
595 |
return delegate().read(b, off, len); |
596 |
} |
597 |
|
598 |
public int available() throws IOException { |
599 |
return delegate().available(); |
600 |
} |
601 |
|
602 |
public boolean markSupported() { |
603 |
return delegate().markSupported(); |
604 |
} |
605 |
|
606 |
public void mark(int readlimit) { |
607 |
delegate().mark(readlimit); |
608 |
} |
609 |
|
610 |
public void close() throws IOException { |
611 |
delegate().close(); |
612 |
} |
613 |
|
614 |
public long skip(long n) throws IOException { |
615 |
return delegate().skip(n); |
616 |
} |
617 |
|
618 |
public void reset() throws IOException { |
619 |
delegate().reset(); |
620 |
} |
621 |
|
549 |
} |
622 |
} |
550 |
|
623 |
|
|
|
624 |
private static final class MultiplexPrintStream extends PrintStream { |
625 |
|
626 |
private final boolean err; |
627 |
|
628 |
public MultiplexPrintStream(boolean err) { |
629 |
this(new NullOutputStream(), err); |
630 |
} |
631 |
|
632 |
private MultiplexPrintStream(NullOutputStream nos, boolean err) { |
633 |
super(nos); |
634 |
nos.throwException = true; |
635 |
this.err = err; |
636 |
} |
637 |
|
638 |
private PrintStream delegate() { |
639 |
ThreadGroup tg = Thread.currentThread().getThreadGroup(); |
640 |
Map/*<ThreadGroup,PrintStream>*/ delegates = err ? delegateErrs : delegateOuts; |
641 |
while (tg != null && !delegates.containsKey(tg)) { |
642 |
tg = tg.getParent(); |
643 |
} |
644 |
PrintStream ps = (PrintStream)delegates.get(tg); |
645 |
if (ps != null) { |
646 |
return ps; |
647 |
} else if (delegating > 0) { |
648 |
PrintStream orig = err ? origErr : origOut; |
649 |
assert orig != null; |
650 |
return orig; |
651 |
} else { |
652 |
// Probably should not happen? But not sure. |
653 |
return err ? System.err : System.out; |
654 |
} |
655 |
} |
656 |
|
657 |
public boolean checkError() { |
658 |
return delegate().checkError(); |
659 |
} |
660 |
|
661 |
public void close() { |
662 |
delegate().close(); |
663 |
} |
664 |
|
665 |
public void flush() { |
666 |
delegate().flush(); |
667 |
} |
668 |
|
669 |
public void print(long l) { |
670 |
delegate().print(l); |
671 |
} |
672 |
|
673 |
public void print(char[] s) { |
674 |
delegate().print(s); |
675 |
} |
676 |
|
677 |
public void print(int i) { |
678 |
delegate().print(i); |
679 |
} |
680 |
|
681 |
public void print(boolean b) { |
682 |
delegate().print(b); |
683 |
} |
684 |
|
685 |
public void print(char c) { |
686 |
delegate().print(c); |
687 |
} |
688 |
|
689 |
public void print(float f) { |
690 |
delegate().print(f); |
691 |
} |
692 |
|
693 |
public void print(double d) { |
694 |
delegate().print(d); |
695 |
} |
696 |
|
697 |
public void print(Object obj) { |
698 |
delegate().print(obj); |
699 |
} |
700 |
|
701 |
public void print(String s) { |
702 |
delegate().print(s); |
703 |
} |
704 |
|
705 |
public void println(double x) { |
706 |
delegate().println(x); |
707 |
} |
708 |
|
709 |
public void println(Object x) { |
710 |
delegate().println(x); |
711 |
} |
712 |
|
713 |
public void println(float x) { |
714 |
delegate().println(x); |
715 |
} |
716 |
|
717 |
public void println(int x) { |
718 |
delegate().println(x); |
719 |
} |
720 |
|
721 |
public void println(char x) { |
722 |
delegate().println(x); |
723 |
} |
724 |
|
725 |
public void println(boolean x) { |
726 |
delegate().println(x); |
727 |
} |
728 |
|
729 |
public void println(String x) { |
730 |
delegate().println(x); |
731 |
} |
732 |
|
733 |
public void println(char[] x) { |
734 |
delegate().println(x); |
735 |
} |
736 |
|
737 |
public void println() { |
738 |
delegate().println(); |
739 |
} |
740 |
|
741 |
public void println(long x) { |
742 |
delegate().println(x); |
743 |
} |
744 |
|
745 |
public void write(int b) { |
746 |
delegate().write(b); |
747 |
} |
748 |
|
749 |
public void write(byte[] b) throws IOException { |
750 |
delegate().write(b); |
751 |
} |
752 |
|
753 |
public void write(byte[] b, int off, int len) { |
754 |
delegate().write(b, off, len); |
755 |
} |
756 |
|
757 |
// XXX printf/format with varargs cannot be overridden here (JDK 1.5 specific) |
758 |
// nor can append(char,CharSequence) |
759 |
// probably does not matter however... |
760 |
|
761 |
} |
762 |
|
551 |
} |
763 |
} |