// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.updates;
import fitnesse.FitNesseContext;
import fitnesse.Updater;
import util.FileUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
public class WikiContentUpdater implements Updater {
private static final Logger LOG = Logger.getLogger(WikiContentUpdater.class.getName());
protected final FitNesseContext context;
private Properties rootProperties;
private String fitNesseVersion;
public WikiContentUpdater(FitNesseContext context) throws IOException {
this.context = context;
rootProperties = loadProperties();
fitNesseVersion = context.version.toString();
}
@Override
public boolean update() throws IOException {
if (shouldUpdate()) {
LOG.info("Unpacking new version of FitNesse resources. Please be patient...");
performAllupdates();
getProperties().put("Version", fitNesseVersion);
saveProperties();
return true;
}
return false;
}
Properties getProperties() {
return rootProperties;
}
Properties loadProperties() throws IOException {
Properties properties = new Properties();
File propFile = getPropertiesFile();
if (propFile.exists()) {
InputStream is = null;
try {
is = new FileInputStream(propFile);
properties.load(is);
} finally {
if (is != null)
is.close();
}
}
return properties;
}
private File getPropertiesFile() {
return new File(context.getRootPagePath(), "properties");
}
void saveProperties() throws IOException {
OutputStream os = null;
File propFile = getPropertiesFile();
try {
os = new FileOutputStream(propFile);
rootProperties.store(os, "#FitNesse properties");
} catch (IOException e) {
String fileName = propFile.getAbsolutePath();
LOG.log(Level.SEVERE, "Failed to save properties file: \"" + fileName + "\". (exception: " + e + ")");
throw e;
} finally {
if (os != null)
os.close();
}
}
boolean performAllupdates() throws IOException {
List<Update> updates = makeAllUpdates();
for (Update update: updates) {
if (update.shouldBeApplied())
performUpdate(update);
}
return true;
}
private void performUpdate(Update update) {
try {
// LOG.info(update.getMessage());
update.doUpdate();
} catch (Exception e) {
LOG.log(Level.SEVERE, "Update failed", e);
}
}
List<Update> makeAllUpdates() throws IOException {
List<Update> updates = new ArrayList<>();
updates.addAll(addAllFilesToBeUpdated("updateList", new UpdateFactory() {
@Override
public Update create(String source, File destination) {
return new ReplacingFileUpdate(source, destination);
}
}));
updates.addAll(addAllFilesToBeUpdated("updateDoNotCopyOverList", new UpdateFactory() {
@Override
public Update create(String source, File destination) {
return new FileUpdate(source, destination);
}
}));
return updates;
}
private List<Update> addAllFilesToBeUpdated(String updateFile, UpdateFactory updateFactory) throws IOException {
String updateFileResource = getCorrectPathFromJar(updateFile);
String[] updateList = parseResource(updateFileResource);
List<Update> updates = new ArrayList<>();
for (String updateableFile : updateList) {
File path = getCorrectPathForTheDestination(updateableFile);
String source = getCorrectPathFromJar(updateableFile);
updates.add(updateFactory.create(source, path));
}
return updates;
}
String getCorrectPathFromJar(String updateableFile) {
return "Resources/" + updateableFile;
}
File getCorrectPathForTheDestination(String updateableFile) {
if (updateableFile.startsWith("FitNesseRoot"))
updateableFile = updateableFile.replace("FitNesseRoot", context.getRootPagePath());
return new File(updateableFile).getParentFile();
}
String[] parseResource(String resourceName) throws IOException {
InputStream in = null;
try {
in = ClassLoader.getSystemResourceAsStream(resourceName);
String content = FileUtil.toString(in);
return content.split("\n");
} finally {
FileUtil.close(in);
}
}
interface UpdateFactory {
Update create(String source, File destination);
}
private boolean shouldUpdate() {
String versionProperty = getProperties().getProperty("Version");
return versionProperty == null || !versionProperty.equals(fitNesseVersion);
}
public void setFitNesseVersion(String version) {
fitNesseVersion = version;
}
}