/* * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.jdi; import com.sun.tools.jdi.*;import com.sun.jdi.*;import com.sun.jdi.connect.*;import com.sun.jdi.InternalException;import java.util.Collections;import java.util.Collection;import java.util.Map;import java.util.List;import java.util.ArrayList;import java.util.Iterator;import java.util.ResourceBundle;import java.io.Serializable; abstract class ConnectorImpl implements Connector { Map<String,Argument> defaultArguments = new java.util.LinkedHashMap<String,Argument>(); // Used by BooleanArgument static String trueString = null; static String falseString; public Map<String,Argument> defaultArguments() { Map<String,Argument> defaults = new java.util.LinkedHashMap<String,Argument>(); Collection values = defaultArguments.values(); Iterator iter = values.iterator(); while (iter.hasNext()) { ArgumentImpl argument = (ArgumentImpl)iter.next(); defaults.put(argument.name(), (Argument)argument.clone()); } return defaults; } void addStringArgument(String name, String label, String description, String defaultValue, boolean mustSpecify) { defaultArguments.put(name, new StringArgumentImpl(name, label, description, defaultValue, mustSpecify)); } void addBooleanArgument(String name, String label, String description, boolean defaultValue, boolean mustSpecify) { defaultArguments.put(name, new BooleanArgumentImpl(name, label, description, defaultValue, mustSpecify)); } void addIntegerArgument(String name, String label, String description, String defaultValue, boolean mustSpecify, int min, int max) { defaultArguments.put(name, new IntegerArgumentImpl(name, label, description, defaultValue, mustSpecify, min, max)); } void addSelectedArgument(String name, String label, String description, String defaultValue, boolean mustSpecify, List<String> list) { defaultArguments.put(name, new SelectedArgumentImpl(name, label, description, defaultValue, mustSpecify, list)); } ArgumentImpl argument(String name, Map arguments) throws IllegalConnectorArgumentsException { ArgumentImpl argument = (ArgumentImpl)arguments.get(name); if (argument == null) { throw new IllegalConnectorArgumentsException( "Argument missing", name); } String value = argument.value(); if (value == null || value.length() == 0) { if (argument.mustSpecify()) { throw new IllegalConnectorArgumentsException( "Argument unspecified", name); } } else if(!argument.isValid(value)) { throw new IllegalConnectorArgumentsException( "Argument invalid", name); } return argument; } private ResourceBundle messages = null; String getString(String key) { if (messages == null) { messages = ResourceBundle.getBundle("com.sun.tools.jdi.resources.jdi"); } return messages.getString(key); } public String toString() { String string = name() + " (defaults: "; Iterator iter = defaultArguments().values().iterator(); boolean first = true; while (iter.hasNext()) { ArgumentImpl argument = (ArgumentImpl)iter.next(); if (!first) { string += ", "; } string += argument.toString(); first = false; } string += ")"; return string; } abstract class ArgumentImpl implements Connector.Argument, Cloneable, Serializable { private String name; private String label; private String description; private String value; private boolean mustSpecify; ArgumentImpl(String name, String label, String description, String value, boolean mustSpecify) { this.name = name; this.label = label; this.description = description; this.value = value; this.mustSpecify = mustSpecify; } public abstract boolean isValid(String value); public String name() { return name; } public String label() { return label; } public String description() { return description; } public String value() { return value; } public void setValue(String value) { if (value == null) { throw new NullPointerException("Can't set null value"); } this.value = value; } public boolean mustSpecify() { return mustSpecify; } public boolean equals(Object obj) { if ((obj != null) && (obj instanceof Connector.Argument)) { Connector.Argument other = (Connector.Argument)obj; return (name().equals(other.name())) && (description().equals(other.description())) && (mustSpecify() == other.mustSpecify()) && (value().equals(other.value())); } else { return false; } } public int hashCode() { return description().hashCode(); } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { // Object should always support clone throw new InternalException(); } } public String toString() { return name() + "=" + value(); } } class BooleanArgumentImpl extends ConnectorImpl.ArgumentImpl implements Connector.BooleanArgument { BooleanArgumentImpl(String name, String label, String description, boolean value, boolean mustSpecify) { super(name, label, description, null, mustSpecify); if(trueString == null) { trueString = getString("true"); falseString = getString("false"); } setValue(value); } /** * Sets the value of the argument. */ public void setValue(boolean value) { setValue(stringValueOf(value)); } /** * Performs basic sanity check of argument. * @return <code>true</code> if value is a string * representation of a boolean value. * @see #stringValueOf(boolean) */ public boolean isValid(String value) { return value.equals(trueString) || value.equals(falseString); } /** * Return the string representation of the <code>value</code> * parameter. * Does not set or examine the value or the argument. * @return the localized String representation of the * boolean value. */ public String stringValueOf(boolean value) { return value? trueString : falseString; } /** * Return the value of the argument as a boolean. Since * the argument may not have been set or may have an invalid * value {@link #isValid(String)} should be called on * {@link #value()} to check its validity. If it is invalid * the boolean returned by this method is undefined. * @return the value of the argument as a boolean. */ public boolean booleanValue() { return value().equals(trueString); } } class IntegerArgumentImpl extends ConnectorImpl.ArgumentImpl implements Connector.IntegerArgument { private final int min; private final int max; IntegerArgumentImpl(String name, String label, String description, String value, boolean mustSpecify, int min, int max) { super(name, label, description, value, mustSpecify); this.min = min; this.max = max; } /** * Sets the value of the argument. * The value should be checked with {@link #isValid(int)} * before setting it; invalid values will throw an exception * when the connection is established - for example, * on {@link LaunchingConnector#launch} */ public void setValue(int value) { setValue(stringValueOf(value)); } /** * Performs basic sanity check of argument. * @return <code>true</code> if value represents an int that is * <code>{@link #min()} <= value <= {@link #max()}</code> */ public boolean isValid(String value) { if (value == null) { return false; } try { return isValid(Integer.decode(value).intValue()); } catch(NumberFormatException exc) { return false; } } /** * Performs basic sanity check of argument. * @return <code>true</code> if * <code>{@link #min()} <= value <= {@link #max()}</code> */ public boolean isValid(int value) { return min <= value && value <= max; } /** * Return the string representation of the <code>value</code> * parameter. * Does not set or examine the value or the argument. * @return the String representation of the * int value. */ public String stringValueOf(int value) { // *** Should this be internationalized???? // *** Even Brian Beck was unsure if an Arabic programmer // *** would expect port numbers in Arabic numerals, // *** so punt for now. return ""+value; } /** * Return the value of the argument as a int. Since * the argument may not have been set or may have an invalid * value {@link #isValid(String)} should be called on * {@link #value()} to check its validity. If it is invalid * the int returned by this method is undefined. * @return the value of the argument as a int. */ public int intValue() { if (value() == null) { return 0; } try { return Integer.decode(value()).intValue(); } catch(NumberFormatException exc) { return 0; } } /** * The upper bound for the value. * @return the maximum allowed value for this argument. */ public int max() { return max; } /** * The lower bound for the value. * @return the minimum allowed value for this argument. */ public int min() { return min; } } class StringArgumentImpl extends ConnectorImpl.ArgumentImpl implements Connector.StringArgument { StringArgumentImpl(String name, String label, String description, String value, boolean mustSpecify) { super(name, label, description, value, mustSpecify); } /** * Performs basic sanity check of argument. * @return <code>true</code> always */ public boolean isValid(String value) { return true; } } class SelectedArgumentImpl extends ConnectorImpl.ArgumentImpl implements Connector.SelectedArgument { private final List<String> choices; SelectedArgumentImpl(String name, String label, String description, String value, boolean mustSpecify, List<String> choices) { super(name, label, description, value, mustSpecify); this.choices = Collections.unmodifiableList(new ArrayList<String>(choices)); } /** * Return the possible values for the argument * @return {@link List} of {@link String} */ public List<String> choices() { return choices; } /** * Performs basic sanity check of argument. * @return <code>true</code> if value is one of {@link #choices()}. */ public boolean isValid(String value) { return choices.contains(value); } }}
/*
* Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.jdi;
import com.sun.tools.jdi.*;
import com.sun.jdi.*;
import com.sun.jdi.connect.*;
import com.sun.jdi.InternalException;
import java.util.Collections;
import java.util.Collection;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.io.Serializable;
abstract class ConnectorImpl implements Connector {
Map<String,Argument> defaultArguments = new java.util.LinkedHashMap<String,Argument>();
// Used by BooleanArgument
static String trueString = null;
static String falseString;
public Map<String,Argument> defaultArguments() {
Map<String,Argument> defaults = new java.util.LinkedHashMap<String,Argument>();
Collection values = defaultArguments.values();
Iterator iter = values.iterator();
while (iter.hasNext()) {
ArgumentImpl argument = (ArgumentImpl)iter.next();
defaults.put(argument.name(), (Argument)argument.clone());
}
return defaults;
}
void addStringArgument(String name, String label, String description,
String defaultValue, boolean mustSpecify) {
defaultArguments.put(name,
new StringArgumentImpl(name, label,
description,
defaultValue,
mustSpecify));
}
void addBooleanArgument(String name, String label, String description,
boolean defaultValue, boolean mustSpecify) {
defaultArguments.put(name,
new BooleanArgumentImpl(name, label,
description,
defaultValue,
mustSpecify));
}
void addIntegerArgument(String name, String label, String description,
String defaultValue, boolean mustSpecify,
int min, int max) {
defaultArguments.put(name,
new IntegerArgumentImpl(name, label,
description,
defaultValue,
mustSpecify,
min, max));
}
void addSelectedArgument(String name, String label, String description,
String defaultValue, boolean mustSpecify,
List<String> list) {
defaultArguments.put(name,
new SelectedArgumentImpl(name, label,
description,
defaultValue,
mustSpecify, list));
}
ArgumentImpl argument(String name, Map arguments)
throws IllegalConnectorArgumentsException {
ArgumentImpl argument = (ArgumentImpl)arguments.get(name);
if (argument == null) {
throw new IllegalConnectorArgumentsException(
"Argument missing", name);
}
String value = argument.value();
if (value == null || value.length() == 0) {
if (argument.mustSpecify()) {
throw new IllegalConnectorArgumentsException(
"Argument unspecified", name);
}
} else if(!argument.isValid(value)) {
throw new IllegalConnectorArgumentsException(
"Argument invalid", name);
}
return argument;
}
private ResourceBundle messages = null;
String getString(String key) {
if (messages == null) {
messages = ResourceBundle.getBundle("com.sun.tools.jdi.resources.jdi");
}
return messages.getString(key);
}
public String toString() {
String string = name() + " (defaults: ";
Iterator iter = defaultArguments().values().iterator();
boolean first = true;
while (iter.hasNext()) {
ArgumentImpl argument = (ArgumentImpl)iter.next();
if (!first) {
string += ", ";
}
string += argument.toString();
first = false;
}
string += ")";
return string;
}
abstract class ArgumentImpl implements Connector.Argument, Cloneable, Serializable {
private String name;
private String label;
private String description;
private String value;
private boolean mustSpecify;
ArgumentImpl(String name, String label, String description,
String value,
boolean mustSpecify) {
this.name = name;
this.label = label;
this.description = description;
this.value = value;
this.mustSpecify = mustSpecify;
}
public abstract boolean isValid(String value);
public String name() {
return name;
}
public String label() {
return label;
}
public String description() {
return description;
}
public String value() {
return value;
}
public void setValue(String value) {
if (value == null) {
throw new NullPointerException("Can't set null value");
}
this.value = value;
}
public boolean mustSpecify() {
return mustSpecify;
}
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof Connector.Argument)) {
Connector.Argument other = (Connector.Argument)obj;
return (name().equals(other.name())) &&
(description().equals(other.description())) &&
(mustSpecify() == other.mustSpecify()) &&
(value().equals(other.value()));
} else {
return false;
}
}
public int hashCode() {
return description().hashCode();
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// Object should always support clone
throw new InternalException();
}
}
public String toString() {
return name() + "=" + value();
}
}
class BooleanArgumentImpl extends ConnectorImpl.ArgumentImpl
implements Connector.BooleanArgument {
BooleanArgumentImpl(String name, String label, String description,
boolean value,
boolean mustSpecify) {
super(name, label, description, null, mustSpecify);
if(trueString == null) {
trueString = getString("true");
falseString = getString("false");
}
setValue(value);
}
/**
* Sets the value of the argument.
*/
public void setValue(boolean value) {
setValue(stringValueOf(value));
}
/**
* Performs basic sanity check of argument.
* @return <code>true</code> if value is a string
* representation of a boolean value.
* @see #stringValueOf(boolean)
*/
public boolean isValid(String value) {
return value.equals(trueString) || value.equals(falseString);
}
/**
* Return the string representation of the <code>value</code>
* parameter.
* Does not set or examine the value or the argument.
* @return the localized String representation of the
* boolean value.
*/
public String stringValueOf(boolean value) {
return value? trueString : falseString;
}
/**
* Return the value of the argument as a boolean. Since
* the argument may not have been set or may have an invalid
* value {@link #isValid(String)} should be called on
* {@link #value()} to check its validity. If it is invalid
* the boolean returned by this method is undefined.
* @return the value of the argument as a boolean.
*/
public boolean booleanValue() {
return value().equals(trueString);
}
}
class IntegerArgumentImpl extends ConnectorImpl.ArgumentImpl
implements Connector.IntegerArgument {
private final int min;
private final int max;
IntegerArgumentImpl(String name, String label, String description,
String value,
boolean mustSpecify, int min, int max) {
super(name, label, description, value, mustSpecify);
this.min = min;
this.max = max;
}
/**
* Sets the value of the argument.
* The value should be checked with {@link #isValid(int)}
* before setting it; invalid values will throw an exception
* when the connection is established - for example,
* on {@link LaunchingConnector#launch}
*/
public void setValue(int value) {
setValue(stringValueOf(value));
}
/**
* Performs basic sanity check of argument.
* @return <code>true</code> if value represents an int that is
* <code>{@link #min()} <= value <= {@link #max()}</code>
*/
public boolean isValid(String value) {
if (value == null) {
return false;
}
try {
return isValid(Integer.decode(value).intValue());
} catch(NumberFormatException exc) {
return false;
}
}
/**
* Performs basic sanity check of argument.
* @return <code>true</code> if
* <code>{@link #min()} <= value <= {@link #max()}</code>
*/
public boolean isValid(int value) {
return min <= value && value <= max;
}
/**
* Return the string representation of the <code>value</code>
* parameter.
* Does not set or examine the value or the argument.
* @return the String representation of the
* int value.
*/
public String stringValueOf(int value) {
// *** Should this be internationalized????
// *** Even Brian Beck was unsure if an Arabic programmer
// *** would expect port numbers in Arabic numerals,
// *** so punt for now.
return ""+value;
}
/**
* Return the value of the argument as a int. Since
* the argument may not have been set or may have an invalid
* value {@link #isValid(String)} should be called on
* {@link #value()} to check its validity. If it is invalid
* the int returned by this method is undefined.
* @return the value of the argument as a int.
*/
public int intValue() {
if (value() == null) {
return 0;
}
try {
return Integer.decode(value()).intValue();
} catch(NumberFormatException exc) {
return 0;
}
}
/**
* The upper bound for the value.
* @return the maximum allowed value for this argument.
*/
public int max() {
return max;
}
/**
* The lower bound for the value.
* @return the minimum allowed value for this argument.
*/
public int min() {
return min;
}
}
class StringArgumentImpl extends ConnectorImpl.ArgumentImpl
implements Connector.StringArgument {
StringArgumentImpl(String name, String label, String description,
String value,
boolean mustSpecify) {
super(name, label, description, value, mustSpecify);
}
/**
* Performs basic sanity check of argument.
* @return <code>true</code> always
*/
public boolean isValid(String value) {
return true;
}
}
class SelectedArgumentImpl extends ConnectorImpl.ArgumentImpl
implements Connector.SelectedArgument {
private final List<String> choices;
SelectedArgumentImpl(String name, String label, String description,
String value,
boolean mustSpecify, List<String> choices) {
super(name, label, description, value, mustSpecify);
this.choices = Collections.unmodifiableList(new ArrayList<String>(choices));
}
/**
* Return the possible values for the argument
* @return {@link List} of {@link String}
*/
public List<String> choices() {
return choices;
}
/**
* Performs basic sanity check of argument.
* @return <code>true</code> if value is one of {@link #choices()}.
*/
public boolean isValid(String value) {
return choices.contains(value);
}
}
}