Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package org.ros.internal.loader;
00018
00019 import com.google.common.base.Preconditions;
00020 import com.google.common.collect.Lists;
00021 import com.google.common.collect.Maps;
00022
00023 import org.ros.CommandLineVariables;
00024 import org.ros.EnvironmentVariables;
00025 import org.ros.address.InetAddressFactory;
00026 import org.ros.exception.RosRuntimeException;
00027 import org.ros.namespace.GraphName;
00028 import org.ros.namespace.NameResolver;
00029 import org.ros.node.NodeConfiguration;
00030 import org.ros.node.NodeMain;
00031
00032 import java.io.File;
00033 import java.net.URI;
00034 import java.net.URISyntaxException;
00035 import java.util.Collections;
00036 import java.util.List;
00037 import java.util.Map;
00038
00046 public class CommandLineLoader {
00047
00048 private final List<String> argv;
00049 private final List<String> nodeArguments;
00050 private final List<String> remappingArguments;
00051 private final Map<String, String> environment;
00052 private final Map<String, String> specialRemappings;
00053 private final Map<GraphName, GraphName> remappings;
00054
00055 private String nodeClassName;
00056
00065 public CommandLineLoader(List<String> argv) {
00066 this(argv, System.getenv());
00067 }
00068
00078 public CommandLineLoader(List<String> argv, Map<String, String> environment) {
00079 Preconditions.checkArgument(argv.size() > 0);
00080 this.argv = argv;
00081 this.environment = environment;
00082 nodeArguments = Lists.newArrayList();
00083 remappingArguments = Lists.newArrayList();
00084 remappings = Maps.newHashMap();
00085 specialRemappings = Maps.newHashMap();
00086 parseArgv();
00087 }
00088
00089 private void parseArgv() {
00090 nodeClassName = argv.get(0);
00091 for (String argument : argv.subList(1, argv.size())) {
00092 if (argument.contains(":=")) {
00093 remappingArguments.add(argument);
00094 } else {
00095 nodeArguments.add(argument);
00096 }
00097 }
00098 }
00099
00100 public String getNodeClassName() {
00101 return nodeClassName;
00102 }
00103
00104 public List<String> getNodeArguments() {
00105 return Collections.unmodifiableList(nodeArguments);
00106 }
00107
00112 public NodeConfiguration build() {
00113 parseRemappingArguments();
00114
00115 NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(getHost());
00116 nodeConfiguration.setParentResolver(buildParentResolver());
00117 nodeConfiguration.setRosRoot(getRosRoot());
00118 nodeConfiguration.setRosPackagePath(getRosPackagePath());
00119 nodeConfiguration.setMasterUri(getMasterUri());
00120 if (specialRemappings.containsKey(CommandLineVariables.NODE_NAME)) {
00121 nodeConfiguration.setNodeName(specialRemappings.get(CommandLineVariables.NODE_NAME));
00122 }
00123 return nodeConfiguration;
00124 }
00125
00126 private void parseRemappingArguments() {
00127 for (String remapping : remappingArguments) {
00128 Preconditions.checkState(remapping.contains(":="));
00129 String[] remap = remapping.split(":=");
00130 if (remap.length > 2) {
00131 throw new IllegalArgumentException("Invalid remapping argument: " + remapping);
00132 }
00133 if (remapping.startsWith("__")) {
00134 specialRemappings.put(remap[0], remap[1]);
00135 } else {
00136 remappings.put(GraphName.of(remap[0]), GraphName.of(remap[1]));
00137 }
00138 }
00139 }
00140
00149 private NameResolver buildParentResolver() {
00150 GraphName namespace = GraphName.root();
00151 if (specialRemappings.containsKey(CommandLineVariables.ROS_NAMESPACE)) {
00152 namespace =
00153 GraphName.of(specialRemappings.get(CommandLineVariables.ROS_NAMESPACE)).toGlobal();
00154 } else if (environment.containsKey(EnvironmentVariables.ROS_NAMESPACE)) {
00155 namespace = GraphName.of(environment.get(EnvironmentVariables.ROS_NAMESPACE)).toGlobal();
00156 }
00157 return new NameResolver(namespace, remappings);
00158 }
00159
00170 private String getHost() {
00171 String host = InetAddressFactory.newLoopback().getHostAddress();
00172 if (specialRemappings.containsKey(CommandLineVariables.ROS_IP)) {
00173 host = specialRemappings.get(CommandLineVariables.ROS_IP);
00174 } else if (environment.containsKey(EnvironmentVariables.ROS_IP)) {
00175 host = environment.get(EnvironmentVariables.ROS_IP);
00176 } else if (environment.containsKey(EnvironmentVariables.ROS_HOSTNAME)) {
00177 host = environment.get(EnvironmentVariables.ROS_HOSTNAME);
00178 }
00179 return host;
00180 }
00181
00192 private URI getMasterUri() {
00193 URI uri = NodeConfiguration.DEFAULT_MASTER_URI;
00194 try {
00195 if (specialRemappings.containsKey(CommandLineVariables.ROS_MASTER_URI)) {
00196 uri = new URI(specialRemappings.get(CommandLineVariables.ROS_MASTER_URI));
00197 } else if (environment.containsKey(EnvironmentVariables.ROS_MASTER_URI)) {
00198 uri = new URI(environment.get(EnvironmentVariables.ROS_MASTER_URI));
00199 }
00200 return uri;
00201 } catch (URISyntaxException e) {
00202 throw new RosRuntimeException("Invalid master URI: " + uri);
00203 }
00204 }
00205
00206 private File getRosRoot() {
00207 if (environment.containsKey(EnvironmentVariables.ROS_ROOT)) {
00208 return new File(environment.get(EnvironmentVariables.ROS_ROOT));
00209 } else {
00210
00211
00212 return null;
00213 }
00214 }
00215
00216 private List<File> getRosPackagePath() {
00217 if (environment.containsKey(EnvironmentVariables.ROS_PACKAGE_PATH)) {
00218 String rosPackagePath = environment.get(EnvironmentVariables.ROS_PACKAGE_PATH);
00219 List<File> paths = Lists.newArrayList();
00220 for (String path : rosPackagePath.split(File.pathSeparator)) {
00221 paths.add(new File(path));
00222 }
00223 return paths;
00224 } else {
00225 return Lists.newArrayList();
00226 }
00227 }
00228
00237 public NodeMain loadClass(String name) throws ClassNotFoundException, InstantiationException,
00238 IllegalAccessException {
00239 Class<?> clazz = getClass().getClassLoader().loadClass(name);
00240 return NodeMain.class.cast(clazz.newInstance());
00241 }
00242 }