/*
* RHQ Management Platform
* Copyright (C) 2012 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* 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 and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.core.pluginapi.util;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.pluginapi.configuration.ListPropertySimpleWrapper;
import org.rhq.core.pluginapi.configuration.MapPropertySimpleWrapper;
/**
* @author Ian Springer
*/
public class StartScriptConfiguration {
public static final String START_SCRIPT_PROP = "startScript";
public static final String START_SCRIPT_PREFIX_PROP = "startScriptPrefix";
public static final String START_SCRIPT_ENV_PROP = "startScriptEnv";
public static final String START_SCRIPT_ARGS_PROP = "startScriptArgs";
private final Log log = LogFactory.getLog(this.getClass());
private Configuration pluginConfig;
public StartScriptConfiguration(Configuration pluginConfig) {
if (pluginConfig == null) {
throw new IllegalArgumentException("'pluginConfig' parameter is null.");
}
this.pluginConfig = pluginConfig;
}
@Nullable
public File getStartScript() {
String startScript = this.pluginConfig.getSimpleValue(START_SCRIPT_PROP);
return (startScript != null) ? new File(startScript) : null;
}
public void setStartScript(File startScript) {
PropertySimple prop = this.pluginConfig.getSimple(START_SCRIPT_PROP);
if (prop == null) {
prop = new PropertySimple(START_SCRIPT_PROP, null);
this.pluginConfig.put(prop);
}
prop.setValue(startScript);
}
@Nullable
public String getStartScriptPrefix() {
return this.pluginConfig.getSimpleValue(START_SCRIPT_PREFIX_PROP);
}
public void setStartScriptPrefix(String startScriptPrefix) {
this.pluginConfig.setSimpleValue(START_SCRIPT_PREFIX_PROP, startScriptPrefix);
}
@NotNull
public Map<String, String> getStartScriptEnv() {
PropertySimple prop = this.pluginConfig.getSimple(START_SCRIPT_ENV_PROP);
Map<String, String> map = (prop != null) ? new MapPropertySimpleWrapper(prop).getValue()
: new HashMap<String, String>();
return map;
}
public void setStartScriptEnv(Map<String, String> startScriptEnv) {
PropertySimple prop = this.pluginConfig.getSimple(START_SCRIPT_ENV_PROP);
if (prop == null) {
prop = new PropertySimple(START_SCRIPT_ENV_PROP, null);
this.pluginConfig.put(prop);
}
try {
new MapPropertySimpleWrapper(prop).setValue(startScriptEnv);
} catch (IllegalArgumentException e) {
setPropertyError(startScriptEnv, prop);
}
}
@NotNull
public List<String> getStartScriptArgs() {
PropertySimple prop = this.pluginConfig.getSimple(START_SCRIPT_ARGS_PROP);
List<String> list = (prop != null) ? new ArgsPropertySimpleWrapper(prop).getValue() : new ArrayList<String>();
return list;
}
public void setStartScriptArgs(List<String> startScriptArgs) {
PropertySimple prop = this.pluginConfig.getSimple(START_SCRIPT_ARGS_PROP);
if (prop == null) {
prop = new PropertySimple(START_SCRIPT_ARGS_PROP, null);
this.pluginConfig.put(prop);
}
try {
new ArgsPropertySimpleWrapper(prop).setValue(startScriptArgs);
} catch (IllegalArgumentException e) {
setPropertyError(startScriptArgs, prop);
}
}
private void setPropertyError(Object rawPropValue, PropertySimple prop) {
prop.setErrorMessage("The discovered value of this property was longer than "
+ PropertySimple.MAX_VALUE_LENGTH
+ " characters (the maximum length of an RHQ property). It has been left unset. Please see the Agent log for the full value.");
log.warn("The discovered value for property [" + prop.getName()
+ "] was too long and was left unset. It is logged here for reference: " + rawPropValue);
}
public Configuration getPluginConfig() {
return pluginConfig;
}
private static class ArgsPropertySimpleWrapper extends ListPropertySimpleWrapper {
public ArgsPropertySimpleWrapper(PropertySimple prop) {
super(prop);
}
// For better readability, put space delimited option values on same line. For example:
// -x some value
// as opposed to:
// -x
// some value
//
@Override
public void setValue(List list) {
String stringValue;
if (list != null && !list.isEmpty()) {
StringBuilder buffer = new StringBuilder(list.get(0).toString());
for (int i = 1; i < list.size(); ++i) {
String arg = list.get(i).toString();
// put options on new line, keep space delimited options on same line
buffer.append(arg.startsWith("-") ? '\n' : ' ').append(arg);
}
stringValue = buffer.toString();
} else {
stringValue = null;
}
// If the value is too long then don't store it, because it will likely invalidate the Map on the way back out.
if (null != stringValue && stringValue.length() > PropertySimple.MAX_VALUE_LENGTH) {
throw new IllegalArgumentException(stringValue);
}
this.prop.setStringValue(stringValue);
}
// Ensure one arg per List entry, split up space delimited options with value on same line. This
// protects users that hand enter in this fashion, and also values entered with the above setter.
@Override
public List<String> getValue() {
List<String> list = new ArrayList<String>();
String stringValue = this.prop.getStringValue();
if (stringValue != null) {
String[] lines = stringValue.split("\n+");
for (String line : lines) {
String element = line.trim();
//element = replacePropertyPatterns(element); // TODO
// separate an option and its value if on one line
if (element.startsWith("-")) {
boolean added = false;
for (int i = 1, len = element.length(); (i < len); ++i) {
char ch = element.charAt(i);
if (ch == ' ' || ch == '\t') {
String option = element.substring(0, i);
String value = element.substring(i).trim();
list.add(option);
if (!value.isEmpty()) {
list.add(value);
}
added = true;
break;
}
}
if (!added) {
list.add(element);
}
} else {
list.add(element);
}
}
}
return list;
}
}
}