/* ==================================================================
* SettingsController.java - Mar 12, 2012 1:31:40 PM
*
* Copyright 2007-2012 SolarNetwork.net Dev Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ==================================================================
*/
package net.solarnetwork.node.setup.web;
import static net.solarnetwork.web.domain.Response.response;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import net.solarnetwork.node.IdentityService;
import net.solarnetwork.node.backup.Backup;
import net.solarnetwork.node.backup.BackupManager;
import net.solarnetwork.node.backup.BackupService;
import net.solarnetwork.node.settings.SettingsBackup;
import net.solarnetwork.node.settings.SettingsCommand;
import net.solarnetwork.node.settings.SettingsService;
import net.solarnetwork.node.setup.web.support.ServiceAwareController;
import net.solarnetwork.util.OptionalService;
import net.solarnetwork.web.domain.Response;
/**
* Web controller for the settings UI.
*
* @author matt
* @version 1.2
*/
@ServiceAwareController
@RequestMapping("/a/settings")
public class SettingsController {
private static final String KEY_PROVIDERS = "providers";
private static final String KEY_PROVIDER_FACTORY = "factory";
private static final String KEY_PROVIDER_FACTORIES = "factories";
private static final String KEY_SETTINGS_SERVICE = "settingsService";
private static final String KEY_SETTINGS_BACKUPS = "settingsBackups";
private static final String KEY_BACKUP_MANAGER = "backupManager";
private static final String KEY_BACKUP_SERVICE = "backupService";
private static final String KEY_BACKUPS = "backups";
@Autowired
@Qualifier("settingsService")
private OptionalService<SettingsService> settingsServiceTracker;
@Autowired
@Qualifier("backupManager")
private OptionalService<BackupManager> backupManagerTracker;
@Autowired
private IdentityService identityService;
@RequestMapping(value = "", method = RequestMethod.GET)
public String settingsList(ModelMap model) {
final SettingsService settingsService = settingsServiceTracker.service();
if ( settingsService != null ) {
model.put(KEY_PROVIDERS, settingsService.getProviders());
model.put(KEY_PROVIDER_FACTORIES, settingsService.getProviderFactories());
model.put(KEY_SETTINGS_SERVICE, settingsService);
model.put(KEY_SETTINGS_BACKUPS, settingsService.getAvailableBackups());
}
final BackupManager backupManager = backupManagerTracker.service();
if ( backupManager != null ) {
model.put(KEY_BACKUP_MANAGER, backupManager);
BackupService service = backupManager.activeBackupService();
model.put(KEY_BACKUP_SERVICE, service);
if ( service != null ) {
List<Backup> backups = new ArrayList<Backup>(service.getAvailableBackups());
Collections.sort(backups, new Comparator<Backup>() {
@Override
public int compare(Backup o1, Backup o2) {
// sort in reverse chronological order (newest to oldest)
return o2.getDate().compareTo(o1.getDate());
}
});
model.put(KEY_BACKUPS, backups);
}
}
return "settings-list";
}
@RequestMapping(value = "/manage", method = RequestMethod.GET)
public String settingsList(@RequestParam(value = "uid", required = true) String factoryUID,
ModelMap model) {
final SettingsService service = settingsServiceTracker.service();
if ( service != null ) {
model.put(KEY_PROVIDERS, service.getProvidersForFactory(factoryUID));
model.put(KEY_PROVIDER_FACTORY, service.getProviderFactory(factoryUID));
model.put(KEY_SETTINGS_SERVICE, service);
}
return "factory-settings-list";
}
@RequestMapping(value = "/manage/add", method = RequestMethod.POST)
@ResponseBody
public Response<String> addConfiguration(
@RequestParam(value = "uid", required = true) String factoryUID) {
final SettingsService service = settingsServiceTracker.service();
String result = null;
if ( service != null ) {
result = service.addProviderFactoryInstance(factoryUID);
}
return response(result);
}
@RequestMapping(value = "/manage/delete", method = RequestMethod.POST)
@ResponseBody
public Response<Object> deleteConfiguration(
@RequestParam(value = "uid", required = true) String factoryUID,
@RequestParam(value = "instance", required = true) String instanceUID) {
final SettingsService service = settingsServiceTracker.service();
if ( service != null ) {
service.deleteProviderFactoryInstance(factoryUID, instanceUID);
}
return response(null);
}
@RequestMapping(value = "/save", method = RequestMethod.POST)
@ResponseBody
public Response<Object> saveSettings(SettingsCommand command, ModelMap model) {
final SettingsService service = settingsServiceTracker.service();
if ( service != null ) {
service.updateSettings(command);
}
return response(null);
}
@RequestMapping(value = "/export", method = RequestMethod.GET)
@ResponseBody
public void exportSettings(@RequestParam(required = false, value = "backup") String backupKey,
HttpServletResponse response) throws IOException {
final SettingsService service = settingsServiceTracker.service();
if ( service != null ) {
response.setContentType(MediaType.TEXT_PLAIN.toString());
response.setHeader("Content-Disposition", "attachment; filename=settings"
+ (backupKey == null ? "" : "_" + backupKey) + ".txt");
if ( backupKey != null ) {
Reader r = service.getReaderForBackup(new SettingsBackup(backupKey, null));
if ( r != null ) {
FileCopyUtils.copy(r, response.getWriter());
}
} else {
service.exportSettingsCSV(response.getWriter());
}
}
}
@RequestMapping(value = "/import", method = RequestMethod.POST)
public String importSettings(@RequestParam("file") MultipartFile file) throws IOException {
final SettingsService service = settingsServiceTracker.service();
if ( !file.isEmpty() && service != null ) {
InputStreamReader reader = new InputStreamReader(file.getInputStream(), "UTF-8");
service.importSettingsCSV(reader);
}
return "redirect:/a/settings";
}
@RequestMapping(value = "/backupNow", method = RequestMethod.POST)
@ResponseBody
public Response<Object> initiateBackup(ModelMap model) {
final BackupManager manager = backupManagerTracker.service();
boolean result = false;
if ( manager != null ) {
manager.createBackup();
result = true;
}
return new Response<Object>(result, null, null, null);
}
@RequestMapping(value = "/exportBackup", method = RequestMethod.GET)
@ResponseBody
public void exportBackup(@RequestParam(required = false, value = "backup") String backupKey,
HttpServletResponse response) throws IOException {
final BackupManager manager = backupManagerTracker.service();
if ( manager == null ) {
return;
}
final Long nodeId = (identityService != null ? identityService.getNodeId() : null);
// create the zip archive for the backup files
response.setContentType("application/zip");
response.setHeader("Content-Disposition",
"attachment; filename=node-" + (nodeId != null ? nodeId.toString() : "UNKNOWN")
+ "-backup" + (backupKey == null ? "" : "-" + backupKey) + ".zip");
manager.exportBackupArchive(backupKey, response.getOutputStream());
}
@RequestMapping(value = "/importBackup", method = RequestMethod.POST)
public String importBackup(@RequestParam("file") MultipartFile file) throws IOException {
final BackupManager manager = backupManagerTracker.service();
if ( manager == null ) {
return "redirect:/a/settings";
}
Map<String, String> props = new HashMap<String, String>();
props.put(BackupManager.BACKUP_KEY, file.getName());
manager.importBackupArchive(file.getInputStream(), props);
return "redirect:/a/settings";
}
}