/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2013 ZAP development team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.zaproxy.zap.extension.ascan; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.swing.table.AbstractTableModel; import org.parosproxy.paros.Constant; import org.parosproxy.paros.core.scanner.HostProcess; import org.parosproxy.paros.core.scanner.Plugin; public class ScanProgressTableModel extends AbstractTableModel { private static final long serialVersionUID = 1L; private static final String[] columnNames = { Constant.messages.getString("ascan.progress.table.name"), Constant.messages.getString("ascan.policy.table.strength"), Constant.messages.getString("ascan.progress.table.progress"), Constant.messages.getString("ascan.progress.table.time"), Constant.messages.getString("ascan.progress.table.reqs"), Constant.messages.getString("ascan.progress.table.status"), }; private List<ScanProgressItem> values; private List<ScanProgressActionIcon> actions = new ArrayList<ScanProgressActionIcon>(); private ScanProgressActionIcon focusedAction; private String totRequests; private String totTime; public ScanProgressTableModel() { super(); values = new ArrayList<ScanProgressItem>(); focusedAction = null; } /** * * @return */ @Override public int getColumnCount() { return columnNames.length; } /** * * @return */ @Override public int getRowCount() { if (values == null) { return 0; } // Add other 2 rows for the final table values... return values.size() + 2; } /** * * @param row * @param col * @return */ @Override public Object getValueAt(int row, int col) { // First check if we're showing the plugin status list if (row < values.size()) { // It's an entry so show the correct values final ScanProgressItem item = values.get(row); switch (col) { case 0: return item.getNameLabel(); case 1: return item.getAttackStrenghtLabel(); case 2: if (item.isCompleted() || item.isRunning() || item.isSkipped()) { return item; } else { return null; } case 3: return getElapsedTimeLabel(item.getElapsedTime()); case 4: return item.getReqCount(); case 5: ScanProgressActionIcon action = null; if (item.isCompleted() || item.isRunning() || item.isSkipped()) { if (row < actions.size()) { action = actions.get(row); action.updateStatus(item); } else { action = new ScanProgressActionIcon(item); actions.add(action); } } return action; default: return null; } // We're in the summary "region", first print an empty // line and then two line of summary (tot time and to requests) // Maybe could be done in a better way, for example using // a dedicated panel positioned on top/bottom of the dialog } else if (row == values.size()) { // The first line after values should be empty return null; } else if (row == (values.size() + 1)) { // The second line after values should contains the totals switch (col) { case 0: return Constant.messages.getString("ascan.progress.label.totals"); case 3: return totTime; case 4: return totRequests; default: return null; } } return null; } /** * * @param rowIndex * @param columnIndex * @return */ @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } /** * * @param col * @return */ @Override public String getColumnName(int col) { return columnNames[col]; } /** * * @param c * @return */ @Override public Class<?> getColumnClass(int c) { switch (c) { case 0: return String.class; case 1: return String.class; case 2: return ScanProgressItem.class; case 3: return String.class; case 4: return ScanProgressActionIcon.class; } return null; } /** * * @return */ public List<ScanProgressItem> getValues() { return values; } /** * * @param icon */ public void setFocusedAction(ScanProgressActionIcon actionIcon) { focusedAction = actionIcon; } /** * * @return */ public ScanProgressActionIcon getFocusedAction() { return focusedAction; } /** * * @param scan */ public void updateValues(ActiveScan scan, HostProcess hp) { values.clear(); // Iterate all Plugins for (Plugin plugin : hp.getCompleted()) { values.add(new ScanProgressItem(hp, plugin, ScanProgressItem.STATUS_COMPLETED)); } for (Plugin plugin : hp.getRunning()) { values.add(new ScanProgressItem(hp, plugin, ScanProgressItem.STATUS_RUNNING)); } for (Plugin plugin : hp.getPending()) { values.add(new ScanProgressItem(hp, plugin, ScanProgressItem.STATUS_PENDING)); } // Update total elapsed time a and request count Date end = (scan.getTimeFinished() == null) ? new Date() : scan.getTimeFinished(); long elapsed = end.getTime() - scan.getTimeStarted().getTime(); totTime = getElapsedTimeLabel(elapsed); totRequests = Integer.toString(scan.getTotalRequests()); this.fireTableDataChanged(); } /** * Inner method for elapsed time label formatting * @param elapsed the time in milliseconds * @return the label with the elapsed time in readable format */ private String getElapsedTimeLabel(long elapsed) { return (elapsed >= 0) ? String.format("%02d:%02d.%03d", elapsed / 60000, (elapsed % 60000) / 1000, (elapsed % 1000)) : null; } }