/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.guvnor.ala.build.maven.executor.gwt; import java.io.BufferedReader; import java.io.File; import java.io.IOException; 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.Optional; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Inject; import org.guvnor.ala.build.maven.config.gwt.GWTCodeServerMavenExecConfig; import org.guvnor.ala.build.maven.model.MavenBuild; import org.guvnor.ala.config.Config; import org.guvnor.ala.exceptions.BuildException; import org.guvnor.ala.pipeline.BiFunctionConfigExecutor; import static org.guvnor.ala.build.maven.util.MavenBuildExecutor.*; import org.slf4j.LoggerFactory; public class GWTCodeServerMavenExecConfigExecutor implements BiFunctionConfigExecutor<MavenBuild, GWTCodeServerMavenExecConfig, MavenBuild> { protected static final org.slf4j.Logger LOG = LoggerFactory.getLogger( GWTCodeServerMavenExecConfigExecutor.class ); private static final String GWT_CODE_SERVER_PORT = "gwt.codeServerPort"; private static final String GWT_CODE_SERVER_LAUNCHER_DIR = "gwt.codeServer.launcherDir"; private static final String GWT_CODE_SERVER_BIND_ADDRESS = "gwt.bindAddress"; private boolean isCodeServerReady = false; private volatile Throwable error = null; private GWTCodeServerPortLeaser leaser; @Inject public GWTCodeServerMavenExecConfigExecutor(GWTCodeServerPortLeaser leaser) { this.leaser = leaser; } @Override public Optional<MavenBuild> apply(final MavenBuild buildConfig, final GWTCodeServerMavenExecConfig config) { final File projectFolder = new File(buildConfig.getProject().getTempDir()); final File webappFolder = new File(projectFolder.getAbsolutePath(), "src/main/webapp"); if ((!leaser.isCodeServerRunning(buildConfig.getProject().getName()))) { LOG.info("> Starting GWT Code Server ... "); final File pom = new File(projectFolder, "pom.xml"); List<String> goals = new ArrayList<>(); goals.add("gwt:run-codeserver"); final Properties properties = new Properties(buildConfig.getProperties()); properties.put(GWT_CODE_SERVER_LAUNCHER_DIR, webappFolder.getAbsolutePath()); Integer portNumber = leaser.getAvailableCodeServerPort().getPortNumber(); leaser.setCodeServerForProject(buildConfig.getProject().getName(), portNumber); properties.put(GWT_CODE_SERVER_PORT, String.valueOf(portNumber)); properties.put(GWT_CODE_SERVER_BIND_ADDRESS, config.getBindAddress()); build(pom, properties, goals); } else { LOG.info("> No need to start GWT Code Server."); } return Optional.of(buildConfig); } @Override public Class<? extends Config> executeFor() { return GWTCodeServerMavenExecConfig.class; } @Override public String outputId() { return "codeServer"; } @Override public String inputId() { return "gwt-codeserver-config"; } public void build(final File pom, final Properties properties, final List<String> goals) throws BuildException { BufferedReader bufferedReader = null; try { StringBuilder sb = new StringBuilder(); final PipedOutputStream baosOut = new PipedOutputStream(); final PipedOutputStream baosErr = new PipedOutputStream(); final PrintStream out = new PrintStream(baosOut, true); final PrintStream err = new PrintStream(baosErr, true); new Thread(() -> executeMaven(pom, out, err, properties, goals.toArray(new String[]{}))).start(); String line; while (!(isCodeServerReady || error != null)) { bufferedReader = new BufferedReader(new InputStreamReader(new PipedInputStream(baosOut))); while ((line = bufferedReader.readLine()) != null) { sb.append(line).append("\n"); if (line.contains("The code server is ready at")) { isCodeServerReady = true; out.close(); err.close(); baosOut.close(); baosErr.close(); LOG.info("> Code Server Started Succesfully."); } } } //@TODO: send line to client } catch (IOException ex) { Logger.getLogger(GWTCodeServerMavenExecConfigExecutor.class.getName()).log(Level.SEVERE, null, ex); } finally { try { bufferedReader.close(); } catch (IOException ex) { Logger.getLogger(GWTCodeServerMavenExecConfigExecutor.class.getName()).log(Level.SEVERE, null, ex); } } } }