1 /* 2 * Zed Attack Proxy (ZAP) and its related class files. 3 * 4 * ZAP is an HTTP/HTTPS proxy for assessing web application security. 5 * 6 * Copyright 2015 The ZAP Development Team 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package org.parosproxy.paros.extension.option; 21 22 import java.awt.BorderLayout; 23 import java.awt.GridBagLayout; 24 import java.io.IOException; 25 import java.nio.charset.StandardCharsets; 26 import java.nio.file.Files; 27 import java.nio.file.Path; 28 import java.nio.file.Paths; 29 import java.util.List; 30 import javax.swing.JLabel; 31 import javax.swing.JPanel; 32 import javax.swing.JSeparator; 33 import javax.swing.SwingConstants; 34 import org.parosproxy.paros.Constant; 35 import org.parosproxy.paros.view.AbstractParamPanel; 36 import org.parosproxy.paros.view.View; 37 import org.zaproxy.zap.utils.ZapLabel; 38 import org.zaproxy.zap.utils.ZapTextField; 39 import org.zaproxy.zap.view.LayoutHelper; 40 import org.zaproxy.zap.view.renderer.SizeBytesStringValue; 41 42 /** 43 * The JVM options panel. 44 * 45 * <p>These options are used by zap.sh and zap.bat when starting ZAP 46 */ 47 public class OptionsJvmPanel extends AbstractParamPanel { 48 49 private static final long serialVersionUID = -7541236934312940852L; 50 private static final Path JVM_PROPERTIES_FILE = 51 Paths.get(Constant.getDefaultHomeDirectory(false), ".ZAP_JVM.properties"); 52 53 /** The name of the options panel. */ 54 private static final String NAME = Constant.messages.getString("jvm.options.title"); 55 56 private static final SizeBytesStringValue sbsv = new SizeBytesStringValue(false); 57 58 /** The text field for the JVM options. */ 59 private ZapTextField jvmOptionsField = null; 60 61 private ZapLabel sizeMemoryLabel = null; 62 private ZapLabel usedMemoryLabel = null; 63 private ZapLabel maxMemoryLabel = null; 64 OptionsJvmPanel()65 public OptionsJvmPanel() { 66 super(); 67 setName(NAME); 68 setLayout(new BorderLayout()); 69 70 JPanel panel = new JPanel(); 71 panel.setLayout(new GridBagLayout()); 72 73 int row = 0; 74 JLabel jvmOptionsLabel = 75 new JLabel(Constant.messages.getString("jvm.options.label.jvmoptions")); 76 jvmOptionsLabel.setLabelFor(getJvmOptionsField()); 77 78 panel.add(jvmOptionsLabel, LayoutHelper.getGBC(0, row, 1, 2.0)); 79 panel.add(getJvmOptionsField(), LayoutHelper.getGBC(1, row, 1, 8.0)); 80 81 panel.add( 82 new JLabel(Constant.messages.getString("jvm.options.warning.restart")), 83 LayoutHelper.getGBC(0, ++row, 2, 1.0)); 84 85 panel.add( 86 new JSeparator(SwingConstants.HORIZONTAL), 87 LayoutHelper.getGBC(0, ++row, 2, 0.0D, 0.0D)); 88 89 panel.add(getSizeMemoryLabel(), LayoutHelper.getGBC(0, ++row, 2, 1.0)); 90 panel.add(getUsedMemoryLabel(), LayoutHelper.getGBC(0, ++row, 2, 1.0)); 91 panel.add(getMaxMemoryLabel(), LayoutHelper.getGBC(0, ++row, 2, 1.0)); 92 93 panel.add(new JLabel(), LayoutHelper.getGBC(0, 10, 1, 0.5D, 1.0D)); // Spacer 94 95 this.add(panel); 96 } 97 getJvmOptionsField()98 private ZapTextField getJvmOptionsField() { 99 if (jvmOptionsField == null) { 100 jvmOptionsField = new ZapTextField(); 101 } 102 return jvmOptionsField; 103 } 104 getSizeMemoryLabel()105 private ZapLabel getSizeMemoryLabel() { 106 if (sizeMemoryLabel == null) { 107 sizeMemoryLabel = new ZapLabel(); 108 } 109 return sizeMemoryLabel; 110 } 111 getUsedMemoryLabel()112 private ZapLabel getUsedMemoryLabel() { 113 if (usedMemoryLabel == null) { 114 usedMemoryLabel = new ZapLabel(); 115 } 116 return usedMemoryLabel; 117 } 118 getMaxMemoryLabel()119 private ZapLabel getMaxMemoryLabel() { 120 if (maxMemoryLabel == null) { 121 maxMemoryLabel = new ZapLabel(); 122 } 123 return maxMemoryLabel; 124 } 125 updateMemoryLabel(ZapLabel labelToUpdate, String key, long value)126 private void updateMemoryLabel(ZapLabel labelToUpdate, String key, long value) { 127 labelToUpdate.setText(Constant.messages.getString(key, sbsv.getString(value))); 128 } 129 130 @Override initParam(Object obj)131 public void initParam(Object obj) { 132 long size = Runtime.getRuntime().totalMemory(); 133 // initParam happens before display of the panel so the values are appropriately set when 134 // viewed 135 updateMemoryLabel(getSizeMemoryLabel(), "jvm.options.memory.size", size); 136 updateMemoryLabel( 137 getUsedMemoryLabel(), 138 "jvm.options.memory.used", 139 size - Runtime.getRuntime().freeMemory()); 140 updateMemoryLabel( 141 getMaxMemoryLabel(), "jvm.options.memory.max", Runtime.getRuntime().maxMemory()); 142 try { 143 /* JVM properties are unusual in that they are held 144 * in a separate file from the other options. 145 * This is for various reasons, including the fact they are used 146 * by the scripts rather than the java code. 147 */ 148 if (Files.exists(JVM_PROPERTIES_FILE)) { 149 List<String> lines = 150 Files.readAllLines(JVM_PROPERTIES_FILE, StandardCharsets.UTF_8); 151 if (lines.size() > 0) { 152 getJvmOptionsField().setText(lines.get(0)); 153 } 154 } 155 } catch (IOException e) { 156 // Ignore 157 } 158 } 159 160 @Override reset()161 public void reset() { 162 getJvmOptionsField().setText(""); 163 saveJvmFile(); 164 } 165 166 @Override saveParam(Object obj)167 public void saveParam(Object obj) throws Exception { 168 saveJvmFile(); 169 } 170 saveJvmFile()171 private void saveJvmFile() { 172 try { 173 String opts = getJvmOptionsField().getText(); 174 if (opts.length() == 0) { 175 // Delete the file so that the 'normal' defaults apply 176 Files.deleteIfExists(JVM_PROPERTIES_FILE); 177 } else { 178 if (!JVM_PROPERTIES_FILE.getParent().toFile().exists()) { 179 // Can happen if the user has only run the dev version not the release one 180 JVM_PROPERTIES_FILE.getParent().toFile().mkdirs(); 181 } 182 // Replace the file contents, even if its just with whitespace 183 Files.write(JVM_PROPERTIES_FILE, opts.getBytes(StandardCharsets.UTF_8)); 184 } 185 } catch (IOException e) { 186 View.getSingleton() 187 .showWarningDialog( 188 this, 189 Constant.messages.getString( 190 "jvm.options.error.writing", 191 JVM_PROPERTIES_FILE.toAbsolutePath(), 192 e.getMessage())); 193 } 194 } 195 196 @Override getHelpIndex()197 public String getHelpIndex() { 198 return "ui.dialogs.options.jvm"; 199 } 200 } 201