| // |
| // ======================================================================== |
| // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| package org.eclipse.jetty.ant; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.PipedInputStream; |
| import java.io.PipedOutputStream; |
| import java.io.PrintStream; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.apache.tools.ant.DefaultLogger; |
| import org.apache.tools.ant.Project; |
| import org.apache.tools.ant.ProjectHelper; |
| import org.eclipse.jetty.toolchain.test.IO; |
| import org.eclipse.jetty.toolchain.test.MavenTestingUtils; |
| |
| public class AntBuild |
| { |
| private Thread _process; |
| private String _ant; |
| |
| private int _port; |
| private String _host; |
| |
| public AntBuild(String ant) |
| { |
| _ant = ant; |
| } |
| |
| private class AntBuildProcess implements Runnable |
| { |
| List<String[]> connList; |
| |
| @Override |
| public void run() |
| { |
| File buildFile = new File(_ant); |
| |
| Project antProject = new Project(); |
| try |
| { |
| antProject.setBaseDir(MavenTestingUtils.getBasedir()); |
| antProject.setUserProperty("ant.file",buildFile.getAbsolutePath()); |
| DefaultLogger logger = new DefaultLogger(); |
| |
| ConsoleParser parser = new ConsoleParser(); |
| //connList = parser.newPattern(".*([0-9]+\\.[0-9]*\\.[0-9]*\\.[0-9]*):([0-9]*)",1); |
| connList = parser.newPattern("Jetty AntTask Started",1); |
| |
| PipedOutputStream pos = new PipedOutputStream(); |
| PipedInputStream pis = new PipedInputStream(pos); |
| |
| PipedOutputStream pose = new PipedOutputStream(); |
| PipedInputStream pise = new PipedInputStream(pose); |
| |
| startPump("STDOUT",parser,pis); |
| startPump("STDERR",parser,pise); |
| |
| logger.setErrorPrintStream(new PrintStream(pos)); |
| logger.setOutputPrintStream(new PrintStream(pose)); |
| logger.setMessageOutputLevel(Project.MSG_VERBOSE); |
| antProject.addBuildListener(logger); |
| |
| antProject.fireBuildStarted(); |
| antProject.init(); |
| |
| ProjectHelper helper = ProjectHelper.getProjectHelper(); |
| |
| antProject.addReference("ant.projectHelper",helper); |
| |
| helper.parse(antProject,buildFile); |
| |
| antProject.executeTarget("jetty.run"); |
| |
| parser.waitForDone(10000,TimeUnit.MILLISECONDS); |
| } |
| catch (Exception e) |
| { |
| antProject.fireBuildFinished(e); |
| } |
| } |
| |
| |
| public void waitForStarted() throws Exception |
| { |
| while (connList == null || connList.isEmpty()) |
| { |
| Thread.sleep(10); |
| } |
| } |
| } |
| |
| public void start() throws Exception |
| { |
| System.out.println("Starting Ant Build ..."); |
| AntBuildProcess abp = new AntBuildProcess(); |
| _process = new Thread(abp); |
| |
| _process.start(); |
| |
| abp.waitForStarted(); |
| |
| // once this has returned we should have the connection info we need |
| //_host = abp.getConnectionList().get(0)[0]; |
| //_port = Integer.parseInt(abp.getConnectionList().get(0)[1]); |
| |
| } |
| |
| public int getJettyPort() |
| { |
| return Integer.parseInt(System.getProperty("jetty.ant.server.port")); |
| } |
| |
| public String getJettyHost() |
| { |
| return System.getProperty("jetty.ant.server.host"); |
| } |
| |
| |
| /** |
| * Stop the jetty server |
| */ |
| public void stop() |
| { |
| System.out.println("Stopping Ant Build ..."); |
| _process.interrupt(); |
| } |
| |
| private static class ConsoleParser |
| { |
| private List<ConsolePattern> patterns = new ArrayList<ConsolePattern>(); |
| private CountDownLatch latch; |
| private int count; |
| |
| public List<String[]> newPattern(String exp, int cnt) |
| { |
| ConsolePattern pat = new ConsolePattern(exp,cnt); |
| patterns.add(pat); |
| count += cnt; |
| |
| return pat.getMatches(); |
| } |
| |
| public void parse(String line) |
| { |
| for (ConsolePattern pat : patterns) |
| { |
| Matcher mat = pat.getMatcher(line); |
| if (mat.find()) |
| { |
| int num = 0, count = mat.groupCount(); |
| String[] match = new String[count]; |
| while (num++ < count) |
| { |
| match[num - 1] = mat.group(num); |
| } |
| pat.getMatches().add(match); |
| |
| if (pat.getCount() > 0) |
| { |
| getLatch().countDown(); |
| } |
| } |
| } |
| } |
| |
| public void waitForDone(long timeout, TimeUnit unit) throws InterruptedException |
| { |
| getLatch().await(timeout,unit); |
| } |
| |
| private CountDownLatch getLatch() |
| { |
| synchronized (this) |
| { |
| if (latch == null) |
| { |
| latch = new CountDownLatch(count); |
| } |
| } |
| |
| return latch; |
| } |
| } |
| |
| private static class ConsolePattern |
| { |
| private Pattern pattern; |
| private List<String[]> matches; |
| private int count; |
| |
| ConsolePattern(String exp, int cnt) |
| { |
| pattern = Pattern.compile(exp); |
| matches = new ArrayList<String[]>(); |
| count = cnt; |
| } |
| |
| public Matcher getMatcher(String line) |
| { |
| return pattern.matcher(line); |
| } |
| |
| public List<String[]> getMatches() |
| { |
| return matches; |
| } |
| |
| public int getCount() |
| { |
| return count; |
| } |
| } |
| |
| private void startPump(String mode, ConsoleParser parser, InputStream inputStream) |
| { |
| ConsoleStreamer pump = new ConsoleStreamer(mode,inputStream); |
| pump.setParser(parser); |
| Thread thread = new Thread(pump,"ConsoleStreamer/" + mode); |
| thread.start(); |
| } |
| |
| /** |
| * Simple streamer for the console output from a Process |
| */ |
| private static class ConsoleStreamer implements Runnable |
| { |
| private String mode; |
| private BufferedReader reader; |
| private ConsoleParser parser; |
| |
| public ConsoleStreamer(String mode, InputStream is) |
| { |
| this.mode = mode; |
| this.reader = new BufferedReader(new InputStreamReader(is)); |
| } |
| |
| public void setParser(ConsoleParser connector) |
| { |
| this.parser = connector; |
| } |
| |
| public void run() |
| { |
| String line; |
| //System.out.printf("ConsoleStreamer/%s initiated%n",mode); |
| try |
| { |
| while ((line = reader.readLine()) != (null)) |
| { |
| if (parser != null) |
| { |
| parser.parse(line); |
| } |
| System.out.println("[" + mode + "] " + line); |
| } |
| } |
| catch (IOException ignore) |
| { |
| /* ignore */ |
| } |
| finally |
| { |
| IO.close(reader); |
| } |
| //System.out.printf("ConsoleStreamer/%s finished%n",mode); |
| } |
| } |
| } |