1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package vogar.commands; 18 19 import java.io.File; 20 import java.io.PrintStream; 21 import java.util.ArrayList; 22 import java.util.Arrays; 23 import java.util.Collection; 24 import java.util.Collections; 25 import java.util.LinkedHashMap; 26 import java.util.List; 27 import java.util.Map; 28 import vogar.Classpath; 29 import vogar.Log; 30 import vogar.Target; 31 32 import static com.google.common.base.Preconditions.checkNotNull; 33 34 /** 35 * Builds a virtual machine command. 36 */ 37 public final class VmCommandBuilder { 38 private final Log log; 39 private File temp; 40 private boolean classpathViaProperty; 41 private Classpath bootClasspath = new Classpath(); 42 private Classpath classpath = new Classpath(); 43 private File userDir; 44 private Integer debugPort; 45 private String mainClass; 46 private PrintStream output; 47 private int maxLength = -1; 48 private List<String> vmCommand = Collections.singletonList("java"); 49 private List<String> vmArgs = new ArrayList<String>(); 50 private List<String> args = new ArrayList<String>(); 51 private File workingDirectory; 52 private Map<String, String> env = new LinkedHashMap<String, String>(); 53 54 public VmCommandBuilder(Log log) { 55 this.log = log; 56 } 57 58 public VmCommandBuilder vmCommand(List<String> vmCommand) { 59 this.vmCommand = new ArrayList<String>(vmCommand); 60 return this; 61 } 62 63 /** 64 * Set the working directory of the target process. 65 */ 66 public VmCommandBuilder workingDirectory(File workingDirectory) { 67 this.workingDirectory = workingDirectory; 68 return this; 69 } 70 71 public VmCommandBuilder temp(File temp) { 72 this.temp = temp; 73 return this; 74 } 75 76 public VmCommandBuilder bootClasspath(Classpath bootClasspath) { 77 this.bootClasspath.addAll(bootClasspath); 78 return this; 79 } 80 81 public VmCommandBuilder classpath(Classpath classpath) { 82 this.classpath.addAll(classpath); 83 return this; 84 } 85 86 public VmCommandBuilder classpathViaProperty(boolean classpathViaProperty) { 87 this.classpathViaProperty = classpathViaProperty; 88 return this; 89 } 90 91 /** 92 * The user dir on the target. This directory might not exist on the 93 * local disk. 94 */ 95 public VmCommandBuilder userDir(File userDir) { 96 this.userDir = userDir; 97 return this; 98 } 99 100 /** 101 * Add a setting for an environment variable in the target process. 102 */ 103 public VmCommandBuilder env(String key, String value) { 104 env.put(key, value); 105 return this; 106 } 107 108 public VmCommandBuilder mainClass(String mainClass) { 109 this.mainClass = mainClass; 110 return this; 111 } 112 113 public VmCommandBuilder output(PrintStream output) { 114 this.output = output; 115 return this; 116 } 117 118 public VmCommandBuilder maxLength(int maxLength) { 119 this.maxLength = maxLength; 120 return this; 121 } 122 123 public VmCommandBuilder vmArgs(String... vmArgs) { 124 return vmArgs(Arrays.asList(vmArgs)); 125 } 126 127 public VmCommandBuilder vmArgs(Collection<String> vmArgs) { 128 this.vmArgs.addAll(vmArgs); 129 return this; 130 } 131 132 public VmCommandBuilder args(String... args) { 133 return args(Arrays.asList(args)); 134 } 135 136 public VmCommandBuilder args(Collection<String> args) { 137 this.args.addAll(args); 138 return this; 139 } 140 141 public Command build(Target target) { 142 // Make sure that the main class to run has been specified. 143 checkNotNull(mainClass, "mainClass may not be null"); 144 145 Target.ScriptBuilder builder = target.newScriptBuilder(); 146 147 if (workingDirectory != null) { 148 builder.workingDirectory(workingDirectory); 149 } 150 151 builder.env(env); 152 153 builder.tokens(vmCommand); 154 if (classpathViaProperty) { 155 builder.tokens("-Djava.class.path=" + classpath); 156 } else { 157 builder.tokens("-classpath", classpath.toString()); 158 } 159 // Only output this if there's something on the boot classpath, 160 // otherwise dalvikvm gets upset. 161 if (!bootClasspath.isEmpty()) { 162 builder.tokens("-Xbootclasspath/a:" + bootClasspath); 163 } 164 if (userDir != null) { 165 builder.tokens("-Duser.dir=" + userDir); 166 } 167 168 if (temp != null) { 169 builder.tokens("-Djava.io.tmpdir=" + temp); 170 } 171 172 builder.tokens(vmArgs); 173 builder.tokens(mainClass); 174 builder.tokens(args); 175 176 return new Command.Builder(log) 177 .args(builder.commandLine()) 178 .tee(output) 179 .maxLength(maxLength) 180 .build(); 181 } 182 } 183