/*************************GO-LICENSE-START*********************************
* Copyright 2014 ThoughtWorks, Inc.
*
* 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.
*************************GO-LICENSE-END***********************************/
package com.thoughtworks.go.domain;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Date;
import com.thoughtworks.go.util.DateUtils;
import com.thoughtworks.go.util.command.IO;
import org.apache.log4j.Logger;
import org.jdom2.Content;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
/**
* Handles the Log element, and subelements, of the CruiseControl configuration file. Also represents the Build Log used
* by the CruiseControl build process.
*/
public class GoControlLog implements Serializable {
private static final long serialVersionUID = -5727569770074024691L;
private static final Logger LOG = Logger.getLogger(GoControlLog.class);
public static final int BEFORE_LENGTH = "logYYYYMMDDhhmmssL".length();
private transient String logDir;
private transient Element buildLog;
/**
* Log instances created this way must have their projectName set.
*/
public GoControlLog() {
reset();
}
public GoControlLog(String defaultWorkingFolder) {
setDir(defaultWorkingFolder);
reset();
}
public void setDir(String logDir) {
this.logDir = logDir;
}
/**
* Writes the current build log to the appropriate directory and filename.
*/
public void writeLogFile(Date now) throws IOException {
String logFilename = decideLogfileName(now);
// Add the logDir as an info element
Element logDirElement = new Element("property");
logDirElement.setAttribute("name", "logdir");
logDirElement.setAttribute("value", new File(logDir).getAbsolutePath());
buildLog.getChild("info").addContent(logDirElement);
// Add the logFile as an info element
Element logFileElement = new Element("property");
logFileElement.setAttribute("name", "logfile");
logFileElement.setAttribute("value", logFilename);
buildLog.getChild("info").addContent(logFileElement);
File logfile = new File(logDir, logFilename);
if (LOG.isDebugEnabled()) {
LOG.debug("Writing log file [" + logfile.getAbsolutePath() + "]");
}
writeLogFile(logfile, buildLog);
}
protected void writeLogFile(File file, Element element) throws IOException {
// Write the log file out, let jdom care about the encoding by using
// an OutputStream instead of a Writer.
OutputStream logStream = null;
try {
Format format = Format.getPrettyFormat();
XMLOutputter outputter = new XMLOutputter(format);
IO.mkdirFor(file);
file.setWritable(true);
logStream = new BufferedOutputStream(new FileOutputStream(file));
outputter.output(new Document(element), logStream);
} finally {
IO.close(logStream);
}
}
public String decideLogfileName(Date now) {
return "log.xml";
}
public static String formatLogFileName(Date date, String label) {
StringBuffer logFileName = new StringBuffer();
logFileName.append("log");
logFileName.append(DateUtils.getFormattedTime(date));
if (label != null) {
logFileName.append("L");
logFileName.append(label);
}
logFileName.append(".xml");
return logFileName.toString();
}
public void addContent(Content newContent) {
buildLog.addContent(newContent);
}
/**
* Resets the build log. After calling this method a fresh build log will exist, ready for adding new content.
*/
public void reset() {
this.buildLog = new Element("cruisecontrol");
}
}