blob: 782237dd043262806b16810b76bf6e0fd8806181 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 University of Illinois All rights reserved. This program
* and the accompanying materials are made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Albert L. Rossi - implementation
* - reworked 05/11/2010
* - version 5.0: now writes to the resourceManager config
******************************************************************************/
package org.eclipse.ptp.rm.pbs.core.templates;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.ptp.core.attributes.IAttributeDefinition;
import org.eclipse.ptp.rm.pbs.core.ConfigUtils;
import org.eclipse.ptp.rm.pbs.core.IPBSNonNLSConstants;
import org.eclipse.ptp.rm.pbs.core.messages.Messages;
import org.eclipse.ptp.rm.pbs.core.rmsystem.PBSResourceManager;
import org.eclipse.ptp.rm.pbs.core.rmsystem.PBSResourceManagerConfiguration;
import org.eclipse.ptp.rtsystem.IRuntimeSystem;
/**
* Controls the selection and configuration of batch script templates.
*
* @see org.eclipse.ptp.rm.pbs.core.templates.PBSBatchScriptTemplate
*
* @author arossi
* @since 5.0
*
*/
public class PBSBatchScriptTemplateManager implements IPBSNonNLSConstants {
private PBSBatchScriptTemplate current;
private final PBSResourceManager resourceManager;
private final IPBSAttributeToTemplateConverter converter;
public PBSBatchScriptTemplateManager(PBSResourceManager rm) throws Throwable {
this.resourceManager = rm;
this.converter = PBSAttributeToTemplateConverterFactory.getConverter(getRMConfig());
configureConverter();
}
public void addImportedTemplate(final File imported) throws Throwable {
String name = imported.getName();
name = validateTemplateNameForEdit(name);
String template = ConfigUtils.readFull(imported, PBSBatchScriptTemplate.BUFFER_SIZE);
if (ZEROSTR.equals(template)) {
throw new Throwable(Messages.PBSBatchScriptTemplateManager_zerostringError);
}
ByteArrayInputStream bais = new ByteArrayInputStream(template.getBytes());
new PBSBatchScriptTemplate(converter).load(bais);
getRMConfig().addTemplate(name, template);
}
public void exportTemplate(final String dir, final String original, final String renamed) throws Throwable {
FileWriter fw = null;
try {
String validated = validateTemplateNameForEdit(renamed);
String template = getRMConfig().getTemplate(original);
if (ZEROSTR.equals(template)) {
throw new Throwable(Messages.PBSBatchScriptTemplateManager_zerostringError);
}
File export = new File(dir, validated);
fw = new FileWriter(export, false);
fw.write(template);
fw.flush();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException t) {
t.printStackTrace();
}
}
}
}
/**
* Looks in the resource manager configuration for all
* <code>_template</code> strings and loads their names.
*/
public String[] findAvailableTemplates() {
PBSResourceManagerConfiguration c = getRMConfig();
if (c == null) {
return new String[0];
}
return c.getTemplateNames();
}
public PBSBatchScriptTemplate getCurrent() {
return current;
}
/**
* Either returns the name of the loaded template, or looks in the
* configuration for the last stored one; if both are undefined, it returns
* "base_template".
*
* @return name
*/
public String getCurrentTemplateName() {
if (current != null) {
return current.getName();
}
PBSResourceManagerConfiguration c = getRMConfig();
if (c != null) {
return c.getCurrentTemplateName();
}
return FULL_TEMPLATE;
}
public PBSResourceManagerConfiguration getRMConfig() {
return (PBSResourceManagerConfiguration) resourceManager.getConfiguration();
}
/**
* The is the full template, with all valid attributes mapped to qsub flags.
*
* @throws Throwable
*/
public boolean handleBaseTemplates() throws Throwable {
PBSResourceManagerConfiguration c = getRMConfig();
if (!configureConverter()) {
return false;
}
String fullTemplate = converter.generateFullBatchScriptTemplate();
if (fullTemplate == null || ZEROSTR.equals(fullTemplate)) {
if (c != null) {
fullTemplate = c.getTemplate(FULL_TEMPLATE);
}
if (fullTemplate == null || ZEROSTR.equals(fullTemplate)) {
return false;
}
return true;
}
if (c != null) {
c.addTemplate(FULL_TEMPLATE, fullTemplate);
String minTemplate = converter.generateMinBatchScriptTemplate();
if (minTemplate != null && !ZEROSTR.equals(minTemplate)) {
c.addTemplate(MIN_TEMPLATE, minTemplate);
}
}
return true;
}
/**
* Constructs a template and calls load using a stream from the serialized
* string stored in the resource manager configuration corresponding to the
* choice parameter. Sets the launch configuration before loading.
*
* @param choice
* name of the template file
* @param config
* current launch configuration
* @return populated template object
*/
public PBSBatchScriptTemplate loadTemplate(String choice, ILaunchConfiguration config) {
PBSResourceManagerConfiguration c = getRMConfig();
if (c == null) {
return null;
}
PBSBatchScriptTemplate template = null;
if (choice == null || ConfigUtils.ZEROSTR.equals(choice)) {
choice = c.getCurrentTemplateName();
}
try {
String serialized = c.getTemplate(choice);
if (serialized == null) {
return null;
}
ByteArrayInputStream bais = new ByteArrayInputStream(serialized.getBytes());
template = new PBSBatchScriptTemplate(converter);
template.setConfiguration(config);
template.load(bais);
template.setName(choice);
if (config != null) {
c.setCurrentTemplateName(choice);
current = template;
}
} catch (Throwable t) {
t.printStackTrace();
}
return template;
}
/**
* Checks first to make sure user is not attempting to remove the base
* template.
*
* @param name
* of template to remove
* @throws IllegalAccessError
*/
public void removeTemplate(String name) throws IllegalAccessError {
if (name.equals(FULL_TEMPLATE) || name.equals(MIN_TEMPLATE)) {
throw new IllegalAccessError(name + Messages.PBSBatchScriptTemplateManager_removeError);
}
PBSResourceManagerConfiguration c = getRMConfig();
if (c != null) {
c.removeTemplate(name);
}
}
/**
* Called after Edit action. Writes content to resource manager
* configuration.
*
* @param editedContent
* of current template
* @param name
* to which to write contents
*/
public void storeTemplate(String editedContent, String name) {
validateTemplateNameForEdit(name);
PBSResourceManagerConfiguration c = getRMConfig();
if (c != null) {
c.addTemplate(name, editedContent);
}
}
/**
* Checks to make sure user is not attempting to overwrite the base
* template.
*
* @param name
* for the template
* @return the name if valid
* @throws IllegalArgumentException
* @throws IllegalAccessError
*/
public String validateTemplateNameForEdit(String name) throws IllegalArgumentException, IllegalAccessError {
if (name.length() == 0) {
throw new IllegalArgumentException(Messages.PBSBatchScriptTemplateManager_illegalArgument);
}
if (!name.endsWith(TEMPLATE_SUFFIX)) {
name = name + TEMPLATE_SUFFIX;
} else if (name.equals(FULL_TEMPLATE) || name.equals(MIN_TEMPLATE)) {
throw new IllegalAccessError(name + Messages.PBSBatchScriptTemplateManager_storeError);
}
return name;
}
/*
* If we are offline, check for the last configuration of attributes for
* this resource manager and use that.
*/
private boolean configureConverter() throws Throwable {
IAttributeDefinition<?, ?, ?>[] modelAttributes = getModelAttributeDefinitions();
if (modelAttributes == null) {
String stored = null;
PBSResourceManagerConfiguration c = getRMConfig();
if (c != null) {
stored = c.getValidAttributeSet();
}
if (stored == null) {
return false;
}
ByteArrayInputStream bais = new ByteArrayInputStream(stored.getBytes());
converter.getData().deserialize(bais);
} else {
converter.setAttributeDefinitions(modelAttributes);
}
converter.initialize();
storeValidAttributeSet(true);
return true;
}
private IAttributeDefinition<?, ?, ?>[] getModelAttributeDefinitions() {
IRuntimeSystem rts = resourceManager.getRuntimeSystem();
if (rts == null) {
return null;
}
IAttributeDefinition<?, ?, ?>[] defs = rts.getAttributeDefinitionManager().getAttributeDefinitions();
if (defs.length == 0) {
return null;
}
return defs;
}
/*
* This is useful for avoiding having to read in the model definition or
* contact the resource manager everytime we reload the manager.
*
* @param force overwrite of current list. If <code>false</code> and the
* list exists, this method simply returns.
*/
private void storeValidAttributeSet(boolean force) throws Throwable {
PBSResourceManagerConfiguration c = getRMConfig();
if (c == null) {
return;
}
if (!force && c.getValidAttributeSet() != null) {
return;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(16 * 1024);
converter.getData().serialize(baos);
c.setValidAttributeSet(baos.toString());
}
}