/********************************************************************************
* CruiseControl, a Continuous Integration Toolkit
* Copyright (c) 2007, ThoughtWorks, Inc.
* 200 E. Randolph, 25th Floor
* Chicago, IL 60601 USA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* + Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* + Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************/
package net.sourceforge.cruisecontrol.dashboard.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sourceforge.cruisecontrol.dashboard.service.BuildLoopQueryService;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import java.io.PrintWriter;
public class GetProjectBuildOutputController implements Controller {
private static final Logger LOGGER = Logger.getLogger(GetProjectBuildOutputController.class);
/** Url parameter name. */
static final String PARAM_OUTPUT_ID = "outputid";
/** Default value initialized in build_detail_observer.js for outputid. */
static final String DEFAULT_OUTPUT_ID = "emptyid";
private final BuildLoopQueryService buildLoopQueryService;
public GetProjectBuildOutputController(BuildLoopQueryService service) {
this.buildLoopQueryService = service;
}
public ModelAndView handleRequest(final HttpServletRequest request, final HttpServletResponse response)
throws Exception {
final String projectName = request.getParameter("project");
final String oldOutputID = request.getParameter(PARAM_OUTPUT_ID);
final String start = request.getParameter("start");
final int startAsInt = (start == null) ? 0 : Integer.parseInt(start);
final String[] output = buildLoopQueryService.getBuildOutput(projectName, startAsInt);
final String newOutputID;
if (output == null || output.length == 0
// see build_detail_observer.js for how outputid default and how is set as a parameter
|| DEFAULT_OUTPUT_ID.equals(oldOutputID)) {
newOutputID = buildLoopQueryService.getLiveOutputID(projectName);
} else {
// only read new ID if output is empty
newOutputID = oldOutputID;
}
final int nextStart = calculateNextStart(oldOutputID, newOutputID, startAsInt, output);
if (LOGGER.isDebugEnabled()) {
final String msg = "*********** ----------- **************"
+ "\nparam start: " + start
+ "\nparam oldOutputID: " + oldOutputID
+ "\nnewOutputID: " + newOutputID
+ "\nnextStart: " + nextStart
+ "\noutput: " + (output == null ? null : "lines: " + output.length)
+ "\n*********** ----------- **************";
LOGGER.debug(msg);
}
response.addHeader("X-JSON", "[" + nextStart + ", \"" + newOutputID + "\"]");
response.setContentType("text/plain");
if (output != null) {
final PrintWriter writer = response.getWriter();
try {
writer.write(StringUtils.join(output, "\n"));
if (output.length > 0) {
response.getWriter().write("\n");
}
} finally {
writer.close();
}
}
return null;
}
int calculateNextStart(final String oldOutputID, final String newOutputID,
final int start, final String[] outputs) {
if (outputs == null || outputs.length == 0) {
// Use OutputID change to determine if logger changed, and reset start line if needed.
if (newOutputID == null || newOutputID.equals(oldOutputID)) {
return start;
} else {
return 0;
}
}
final String firstLine = outputs[0];
if (firstLine.startsWith("Skipped") && firstLine.endsWith("lines")) {
final String skippedLines = StringUtils.remove(StringUtils.remove(firstLine, "Skipped"), "lines").trim();
return start + Integer.parseInt(skippedLines) + outputs.length - 1;
}
return start + outputs.length;
}
}