GridTab.java

Index Score
org.compiere.model
Compiere

View: Reasons, Metrics, Source Code

These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.

MetricDescription
EXEC_COMMENTSComments in executable code
JAVA0034JAVA0034 Missing braces in if statement
DECL_COMMENTSComments in declarations
LINE_COMMENTNumber of line comments
CYCLOMATICCyclomatic complexity
DOC_COMMENTNumber of javadoc comment lines
LINESNumber of lines in the source file
COMMENTSComment lines
LOCLines of code
ELOCEffective lines of code
SIZESize of the file in bytes
RETURNSNumber of return points from functions
COMPARISONSNumber of comparison operators
EXITSProcedure exits
LOGICAL_LINESNumber of statements
OPERATORSNumber of operators
PROGRAM_LENGTHHalstead program length
OPERANDSNumber of operands
FUNCTIONSNumber of function declarations
UNIQUE_OPERANDSNumber of unique operands
BLOCKSNumber of blocks
INTERFACE_COMPLEXITYInterface complexity
PROGRAM_VOCABHalstead program vocabulary
JAVA0145JAVA0145 Tab character used in source file
LOOPSNumber of loops
PARAMSNumber of formal parameter declarations
JAVA0143JAVA0143 Synchronized method
WHITESPACENumber of whitespace lines
JAVA0166JAVA0166 Generic exception caught
JAVA0035JAVA0035 Missing braces in for statement
JAVA0287JAVA0287 Unnecessary null check
JAVA0082JAVA0082 Unnecessary widening cast
JAVA0163JAVA0163 Empty statement
UNIQUE_OPERATORSNumber of unique operators
JAVA0117JAVA0117 Missing javadoc: method 'method'
PROGRAM_VOLUMEHalstead program volume
JAVA0136JAVA0136 N methods defined in class (maximum: M)
JAVA0126JAVA0126 Method declares unchecked exception in throws
JAVA0110JAVA0110 Incorrect javadoc: no @return tag
JAVA0087JAVA0087 Use of Thread.sleep()
JAVA0100JAVA0100 Class contains N non-final fields (maximum: M)
JAVA0108JAVA0108 Incorrect javadoc: no @param tag for 'parameter'
JAVA0003JAVA0003 Minimize use of on-demand (.*) imports
JAVA0270JAVA0270 Use Java 5.0 enhanced for loop construct to iterate over all elements in an array
NEST_DEPTHMaximum nesting depth
/****************************************************************************** * Product: Compiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2007 ComPiere, Inc. All Rights Reserved. * * This program is free software, you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program 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 for more details. * * You should have received a copy of the GNU General Public License along * * with this program, if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 3600 Bridge Parkway #102, Redwood City, CA 94065, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package org.compiere.model; import java.beans.*; import java.io.*; import java.sql.*; import java.text.*; import java.util.*; import java.util.logging.*; import javax.swing.event.*; import org.compiere.controller.*; import org.compiere.framework.*; import org.compiere.util.*; /** * Tab Model. * - a combination of AD_Tab (the display attributes) and AD_Table information. * <p> * The Tab owns also it's Table model * and listens to data changes to update the Field values. * * <p> * The Tab maintains the bound property: CurrentRow * * <pre> * Event Hierarchies: * - dataChanged (from MTable) * - setCurrentRow * - Update all Field Values * * - setValue * - Update Field Value * - Callout * </pre> * @author Jorg Janke * @version $Id: GridTab.java,v 1.10 2006/10/02 05:18:39 jjanke Exp $ */ public class GridTab implements DataStatusListener, Evaluatee, Serializable { /** * */ private static final long serialVersionUID = 1L; /** * Create Tab (Model) from Value Object. * <p> * MTab provides a property listener for changed rows and a * DataStatusListener for communicating changes of the underlying data * @param vo Value Object * @param onlyCurrentDays only current days */ public GridTab(GridTabVO vo, int onlyCurrentDays) { m_vo = vo; m_vo.onlyCurrentDays = onlyCurrentDays; // Create MTable m_mTable = new GridTable (m_vo.ctx, m_vo.AD_Table_ID, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true); m_mTable.setReadOnly(m_vo.IsReadOnly || m_vo.IsView); m_mTable.setDeleteable(m_vo.IsDeleteable); initTab(false); } // GridTab /** Value Object */ private GridTabVO m_vo; /** The Table Model for Query */ private GridTable m_mTable = null; private String m_keyColumnName = ""; private String m_linkColumnName = ""; private String m_extendedWhere; /** Attachments */ private HashMap<Integer,Integer> m_Attachments = null; /** Chats */ private HashMap<Integer,Integer> m_Chats = null; /** Locks */ private ArrayList<Integer> m_Lock = null; /** Current Row */ private int m_currentRow = -1; /** Property Change */ private PropertyChangeSupport m_propertyChangeSupport = new PropertyChangeSupport(this); /** Property Change Type */ public static final String PROPERTY = "CurrentRow"; /** A list of event listeners for this component. */ protected EventListenerList m_listenerList = new EventListenerList(); /** Current Data Status Event */ private DataStatusEvent m_DataStatusEvent = null; /** Query */ private Query m_query = new Query(); private String m_oldQuery = "0=9"; private String m_linkValue = "999999"; /** Order By Array if SortNo 1..3 */ private String[] m_OrderBys = new String[3]; /** List of Key Parents */ private ArrayList<String> m_parents = new ArrayList<String>(2); /** Map of ColumnName of source field (key) and the dependant field (value) */ private MultiMap<String,GridField> m_depOnField = new MultiMap<String,GridField>(); /** Is Tab Included in other Tab */ private boolean m_included = false; /** Logger */ protected CLogger log = CLogger.getCLogger(getClass()); /************************************************************************** * Tab loader for Tabs > 0 */ class Loader extends Thread { /** * Async Loading of Tab > 0 */ public void run() { initTab (true); } // run } // Loader /** * Initialize Tab with record from AD_Tab_v * @param async async * @return true, if correctly initialized (ignored) */ protected boolean initTab (boolean async) { log.fine("#" + m_vo.TabNo + " - Async=" + async + " - Where=" + m_vo.WhereClause); m_extendedWhere = m_vo.WhereClause; // Get Field Data if (!loadFields()) { return false; } // Order By m_mTable.setOrderClause(getOrderByClause(m_vo.onlyCurrentDays)); if (async) log.fine("#" + m_vo.TabNo + " - Async=" + async + " - fini"); return true; } // initTab /** * Dispose - clean up resources */ protected void dispose() { log.fine("#" + m_vo.TabNo); m_OrderBys = null; // m_parents.clear(); m_parents = null; // m_mTable.close (true); // also disposes Fields m_mTable = null; // m_depOnField.clear(); m_depOnField = null; if (m_Attachments != null) m_Attachments.clear(); m_Attachments = null; if (m_Chats != null) m_Chats.clear(); m_Chats = null; // m_vo.Fields.clear(); m_vo.Fields = null; m_vo = null; } // dispose /** * Get Field data and add to MTable, if it's required or displayed. * Reqiored fields are keys, parents, or standard Columns * @return true if fields loaded */ private boolean loadFields() { log.fine("#" + m_vo.TabNo); if (m_vo.Fields == null) return false; // Add Fields for (int f = 0; f < m_vo.Fields.size(); f++) { GridFieldVO voF = (GridFieldVO)m_vo.Fields.get(f); // Add Fields to Table if (voF != null) { GridField field = new GridField (voF); String columnName = field.getColumnName(); // Record Info if (field.isKey()) m_keyColumnName = columnName; // Parent Column(s) if (field.isParentColumn()) m_parents.add(columnName); // Order By int sortNo = field.getSortNo(); if (sortNo == 0) ; else if (Math.abs(sortNo) == 1) { m_OrderBys[0] = columnName; if (sortNo < 0) m_OrderBys[0] += " DESC"; } else if (Math.abs(sortNo) == 2) { m_OrderBys[1] = columnName; if (sortNo < 0) m_OrderBys[1] += " DESC"; } else if (Math.abs(sortNo) == 3) { m_OrderBys[2] = columnName; if (sortNo < 0) m_OrderBys[2] += " DESC"; } // Add field m_mTable.addField(field); // List of ColumnNames, this field is dependent on ArrayList<String> list = field.getDependentOn(); for (int i = 0; i < list.size(); i++) m_depOnField.put(list.get(i), field); // ColumnName, Field // Add fields all fields are dependent on if (columnName.equals("IsActive") || columnName.equals("Processed") || columnName.equals("Processing")) m_depOnField.put(columnName, null); } } // for all fields // Add Standard Fields if (m_mTable.getField("Created") == null) { GridField created = new GridField (GridFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, true, true)); m_mTable.addField(created); } if (m_mTable.getField("CreatedBy") == null) { GridField createdBy = new GridField (GridFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, true, false)); m_mTable.addField(createdBy); } if (m_mTable.getField("Updated") == null) { GridField updated = new GridField (GridFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, false, true)); m_mTable.addField(updated); } if (m_mTable.getField("UpdatedBy") == null) { GridField updatedBy = new GridField (GridFieldVO.createStdField(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, m_vo.AD_Window_ID, m_vo.AD_Tab_ID, false, false, false)); m_mTable.addField(updatedBy); } return true; } // loadFields /** * Get a list of variables, this tab is dependent on. * - for display purposes * @return ArrayList */ public ArrayList<String> getDependentOn() { ArrayList<String> list = new ArrayList<String>(); // Display Evaluator.parseDepends(list, m_vo.DisplayLogic); // if (list.size() > 0 && CLogMgt.isLevelFiner()) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < list.size(); i++) sb.append(list.get(i)).append(" "); log.finer("(" + m_vo.Name + ") " + sb.toString()); } return list; } // getDependentOn /** * Get Display Logic * @return display logic */ public String getDisplayLogic() { return m_vo.DisplayLogic; } // getDisplayLogic /** * Get TableModel. * <B>Do not directly communicate with the table model, * but through the methods of this class</B> * @return Table Model */ public GridTable getTableModel() { return m_mTable; } // getTableModel /** * Get Tab Icon * @return Icon */ public javax.swing.Icon getIcon() { if (m_vo.AD_Image_ID == 0) return null; // /** @todo Load Image */ return null; } // getIcon /************************************************************************** * Has this field dependents ? * @param columnName column name * @return true if column has dependent */ public boolean hasDependants (String columnName) { // m_depOnField.printToLog(); return m_depOnField.containsKey(columnName); } // isDependentOn /** * Get dependents fields of columnName * @param columnName column name * @return ArrayList with GridFields dependent on columnName */ public ArrayList<GridField> getDependantFields (String columnName) { return m_depOnField.getValues(columnName); } // getDependentFields /************************************************************************** * Set Query * @param query query */ public void setQuery(Query query) { if (query == null) m_query = new Query(); else { m_query = query; m_vo.onlyCurrentDays = 0; } } // setQuery /** * Get Query * @return query */ public Query getQuery() { return m_query; } // getQuery /** * Is Query Active * @return true if query active */ public boolean isQueryActive() { if (m_query != null) return m_query.isActive(); return false; } // isQueryActive /** * Is Query New Record * @return true if query active */ public boolean isQueryNewRecord() { if (m_query != null) return m_query.isNewRecordQuery(); return false; } // isQueryNewRecord /** * Enable Events - enable data events of tabs (add listeners) */ public void enableEvents() { // Setup Events m_mTable.addDataStatusListener(this); // m_mTable.addTableModelListener(this); } // enableEvents /** * Assemble whereClause and query MTable and position to row 0. * <pre> * Scenarios: * - Never opened (full query) * - query changed (full query) * - Detail link value changed (full query) * - otherwise (refreshAll) * </pre> * @param onlyCurrentDays only current rows */ public void query (int onlyCurrentDays) { query (onlyCurrentDays, 0, false); // updated } // query /** * Assemble whereClause and query MTable and position to row 0. * <pre> * Scenarios: * - Never opened (full query) * - query changed (full query) * - Detail link value changed (full query) * - otherwise (refreshAll) * </pre> * @param onlyCurrentDays if only current row, how many days back * @param maxRows maximum rows or 0 for all * @param created query based on created if true otherwise updated * @return true if queried successfully */ public boolean query (int onlyCurrentDays, int maxRows, boolean created) { log.fine("#" + m_vo.TabNo + " - OnlyCurrentDays=" + onlyCurrentDays + ", Detail=" + isDetail()); boolean success = true; // is it same query? boolean refresh = m_oldQuery.equals(m_query.getWhereClause()) && m_vo.onlyCurrentDays == onlyCurrentDays; m_oldQuery = m_query.getWhereClause(); m_vo.onlyCurrentDays = onlyCurrentDays; /** * Set Where Clause */ // Tab Where Clause StringBuffer where = new StringBuffer(m_vo.WhereClause); if (m_vo.onlyCurrentDays > 0) { if (where.length() > 0) where.append(" AND "); boolean showNotProcessed = findColumn ("Processed") != -1; // Show only unprocessed or the one updated within x days if (showNotProcessed) where.append("(Processed='N' OR "); if (created) where.append("Created>="); else where.append("Updated>="); // where.append("addDays(current_timestamp, -"); where.append("addDays(SysDate, -") .append(m_vo.onlyCurrentDays).append(")"); if (showNotProcessed) where.append(")"); } // Detail Query if (isDetail()) { String lc = getLinkColumnName(); if (lc.equals("")) { log.warning ("No link column"); if (where.length() > 0) where.append(" AND "); where.append (" 2=3"); success = false; } else { String value = m_vo.ctx.getContext( m_vo.WindowNo, lc); // Same link value? if (refresh) refresh = m_linkValue.equals(value); m_linkValue = value; // Check validity if (value.length() == 0) { log.warning ("No value for link column " + lc); if (where.length() > 0) where.append(" AND "); where.append (" 2=4"); success = false; } else { // we have column and value if (where.length() > 0) where.append(" AND "); if ("NULL".equals(value.toUpperCase())) { where.append(lc).append(" IS NULL "); log.severe("Null Value of link column " + lc); } else { where.append(lc).append("="); if (lc.endsWith("_ID")) where.append(value); else where.append("'").append(value).append("'"); } } } } // isDetail m_extendedWhere = where.toString(); // Final Query if (m_query.isActive()) { String q = validateQuery(m_query); if (q != null) { if (where.length() > 0 ) where.append(" AND "); where.append(q); } } /** * Query */ log.fine("#" + m_vo.TabNo + " - " + where); if (m_mTable.isOpen()) { if (refresh) m_mTable.dataRefreshAll(); else m_mTable.dataRequery(where.toString()); } else { m_mTable.setSelectWhereClause(where.toString()); m_mTable.open(maxRows); } // Go to Record 0 setCurrentRow(0, true); return success; } // query /** * Validate Query. * If query column is not a tab column create EXISTS query * @param query query * @return where clause */ private String validateQuery (Query query) { if (query == null || query.getRestrictionCount() == 0) return null; // Check: only one restriction if (query.getRestrictionCount() != 1) { log.fine("Ignored(More than 1 Restriction): " + query); return query.getWhereClause(); } String colName = query.getColumnName(0); if (colName == null) { log.fine("Ignored(No Column): " + query); return query.getWhereClause(); } // a '(' in the name = function - don't try to resolve if (colName.indexOf('(') != -1) { log.fine("Ignored(Function): " + colName); return query.getWhereClause(); } // OK - Query is valid // Zooms to the same Window (Parents, ..) String refColName = null; if (colName.equals("R_RequestRelated_ID")) refColName = "R_Request_ID"; else if (colName.startsWith("C_DocType")) refColName = "C_DocType_ID"; else if (colName.equals("CreatedBy") || colName.equals("UpdatedBy")) refColName = "AD_User_ID"; else if (colName.equals("Orig_Order_ID")) refColName = "C_Order_ID"; else if (colName.equals("Orig_InOut_ID")) refColName = "M_InOut_ID"; if (refColName != null) { query.setColumnName(0, refColName); if (getField(refColName) != null) { log.fine("Column " + colName + " replaced with synonym " + refColName); return query.getWhereClause(); } refColName = null; } // Simple Query. if (getField(colName) != null) { log.fine("Field Found: " + colName); return query.getWhereClause(); } // Find Refernce Column e.g. BillTo_ID -> C_BPartner_Location_ID String sql = "SELECT cc.ColumnName " + "FROM AD_Column c" + " INNER JOIN AD_Ref_Table r ON (c.AD_Reference_Value_ID=r.AD_Reference_ID)" + " INNER JOIN AD_Column cc ON (r.Column_Key_ID=cc.AD_Column_ID) " + "WHERE c.AD_Reference_ID IN (18,30)" // Table/Search + " AND c.ColumnName=?"; try { PreparedStatement pstmt = DB.prepareStatement(sql, null); pstmt.setString(1, colName); ResultSet rs = pstmt.executeQuery(); if (rs.next()) refColName = rs.getString(1); rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, "(ref) - Column=" + colName, e); return query.getWhereClause(); } // Reference Column found if (refColName != null) { query.setColumnName(0, refColName); if (getField(refColName) != null) { log.fine("Column " + colName + " replaced with " + refColName); return query.getWhereClause(); } colName = refColName; } // Column NOT in Tab - create EXISTS subquery String tableName = null; String tabKeyColumn = getKeyColumnName(); // Column=SalesRep_ID, Key=AD_User_ID, Query=SalesRep_ID=101 sql = "SELECT t.TableName " + "FROM AD_Column c" + " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID) " + "WHERE c.ColumnName=? AND IsKey='Y'" // #1 Link Column + " AND EXISTS (SELECT * FROM AD_Column cc" + " WHERE cc.AD_Table_ID=t.AD_Table_ID AND cc.ColumnName=?)"; // #2 Tab Key Column try { PreparedStatement pstmt = DB.prepareStatement(sql, null); pstmt.setString(1, colName); pstmt.setString(2, tabKeyColumn); ResultSet rs = pstmt.executeQuery(); if (rs.next()) tableName = rs.getString(1); rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, "Column=" + colName + ", Key=" + tabKeyColumn, e); return null; } // Special Reference Handling if (tabKeyColumn.equals("AD_Reference_ID")) { // Column=AccessLevel, Key=AD_Reference_ID, Query=AccessLevel='6' sql = "SELECT AD_Reference_ID FROM AD_Column WHERE ColumnName=?"; int AD_Reference_ID = DB.getSQLValue(null, sql, colName); return "AD_Reference_ID=" + AD_Reference_ID; } // Causes could be functions in query // e.g. Column=UPPER(Name), Key=AD_Element_ID, Query=UPPER(AD_Element.Name) LIKE '%CUSTOMER%' if (tableName == null) { log.info ("Not successfull - Column=" + colName + ", Key=" + tabKeyColumn + ", Query=" + query); return query.getWhereClause(); } query.setTableName("xx"); StringBuffer result = new StringBuffer ("EXISTS (SELECT * FROM ") .append(tableName).append(" xx WHERE ") .append(query.getWhereClause(true)) .append(" AND xx.").append(tabKeyColumn).append("=") .append(getTableName()).append(".").append(tabKeyColumn).append(")"); log.fine(result.toString()); return result.toString(); } // validateQuery /************************************************************************** * Refresh all data */ public void dataRefreshAll () { log.fine("#" + m_vo.TabNo); /** @todo does not work with alpha key */ int keyNo = m_mTable.getKeyID(m_currentRow); m_mTable.dataRefreshAll(); // Should use RowID - not working for tables with multiple keys if (keyNo != -1) { if (keyNo != m_mTable.getKeyID(m_currentRow)) // something changed { int size = getRowCount(); for (int i = 0; i < size; i++) { if (keyNo == m_mTable.getKeyID(i)) { m_currentRow = i; break; } } } } setCurrentRow(m_currentRow, true); } // dataRefreshAll /** * Refresh current row data */ public void dataRefresh () { dataRefresh (m_currentRow); } // dataRefresh /** * Refresh row data * @param row index */ public void dataRefresh (int row) { log.fine("#" + m_vo.TabNo + " - row=" + row); m_mTable.dataRefresh(row); setCurrentRow(row, true); } // dataRefresh /************************************************************************** * Uncoditionally Save data * @param manualCmd if true, no vetoable PropertyChange will be fired for save confirmation from MTable * @return true if save complete (or nor required) */ public boolean dataSave(boolean manualCmd) { log.fine("#" + m_vo.TabNo + " - row=" + m_currentRow); try { boolean retValue = (m_mTable.dataSave(manualCmd) == GridTable.SAVE_OK); if (manualCmd) setCurrentRow(m_currentRow, false); return retValue; } catch (Exception e) { log.log(Level.SEVERE, "#" + m_vo.TabNo + " - row=" + m_currentRow, e); } return false; } // dataSave /** * Do we need to Save? * @param rowChange row change * @param onlyRealChange if true the value of a field was actually changed * (e.g. for new records, which have not been changed) - default false * @return true it needs to be saved */ public boolean needSave (boolean rowChange, boolean onlyRealChange) { if (rowChange) { return m_mTable.needSave(-2, onlyRealChange); } else { if (onlyRealChange) return m_mTable.needSave(); else return m_mTable.needSave(onlyRealChange); } } // isDataChanged /** * Ignore data changes */ public void dataIgnore() { log.fine("#" + m_vo.TabNo); m_mTable.dataIgnore(); setCurrentRow(m_currentRow, false); // re-load data log.fine("#" + m_vo.TabNo + "- fini"); } // dataIgnore /** * Create (copy) new Row * and process Callouts * @param copy copy * @return true if copied/new */ public boolean dataNew (boolean copy) { log.fine("#" + m_vo.TabNo); if (!isInsertRecord()) { log.warning ("Insert Not allowed in TabNo=" + m_vo.TabNo); return false; } // Prevent New Where Main Record is processed if (m_vo.TabNo > 0) { boolean processed = "Y".equals(m_vo.ctx.getContext( m_vo.WindowNo, "Processed")); // boolean active = "Y".equals(m_vo.ctx.getContext( m_vo.WindowNo, "IsActive")); if (processed) { log.warning ("Not allowed in TabNo=" + m_vo.TabNo + " -> Processed=" + processed); return false; } log.finest("Processed=" + processed); } boolean retValue = m_mTable.dataNew (m_currentRow, copy); if (!retValue) return retValue; setCurrentRow(m_currentRow + 1, true); // process all Callouts (no dependency check - assumed that settings are valid) for (int i = 0; i < getFieldCount(); i++) processCallout(getField(i)); // check validity of defaults for (int i = 0; i < getFieldCount(); i++) { getField(i).refreshLookup(); getField(i).validateValue(); getField(i).setError(false); } m_mTable.setChanged(false); return retValue; } // dataNew /** * Delete current Row * @return true if deleted */ public boolean dataDelete() { log.fine("#" + m_vo.TabNo + " - row=" + m_currentRow); boolean retValue = m_mTable.dataDelete(m_currentRow); setCurrentRow(m_currentRow, true); return retValue; } // dataDelete /** * Get Name of Tab * @return name */ public String getName() { return m_vo.Name; } // getName /** * Get Description of Tab * @return description */ public String getDescription() { return m_vo.Description; } // getDescription /** * Get Help of Tab * @return help */ public String getHelp() { return m_vo.Help; } // getHelp /** * Get Tab Level * @return tab level */ public int getTabLevel() { return m_vo.TabLevel; } // getTabLevel /** * Get Commit Warning * @return commit warning */ public String getCommitWarning() { return m_vo.CommitWarning; } // getCommitWarning /** * Return Table Model * @return MTable */ protected GridTable getMTable() { return m_mTable; } // getMTable /** * Return the name of the key column - may be "" * @return key column name */ public String getKeyColumnName() { return m_keyColumnName; } // getKeyColumnName /** * Return Name of link column * @return link column name */ public String getLinkColumnName() { return m_linkColumnName; } // getLinkColumnName /** * Set Name of link column. * Set from MWindow.loadTabData * Used in MTab.isCurreny, (.setCurrentRow) .query - APanel.cmd_report * and MField.isEditable and .isDefault via context * @param linkColumnName name of column - or sets name to AD_Column_ID, if exists */ public void setLinkColumnName (String linkColumnName) { if (linkColumnName != null) m_linkColumnName = linkColumnName; else { if (m_vo.AD_Column_ID == 0) return; // we have a link column identified (primary parent column) else { String SQL = "SELECT ColumnName FROM AD_Column WHERE AD_Column_ID=?"; try { PreparedStatement pstmt = DB.prepareStatement(SQL, null); pstmt.setInt(1, m_vo.AD_Column_ID); // Parent Link Column ResultSet rs = pstmt.executeQuery(); if (rs.next()) m_linkColumnName = rs.getString(1); rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, "", e); } log.fine("AD_Column_ID=" + m_vo.AD_Column_ID + " - " + m_linkColumnName); } } m_vo.ctx.setContext(m_vo.WindowNo, m_vo.TabNo, "LinkColumnName", m_linkColumnName); } // setLinkColumnName /** * Is the tab current?. * <pre> * Yes - Table must be open * - Query String is the same * - Not Detail * - Old link column value is same as current one * </pre> * @return true if current */ public boolean isCurrent() { // Open? if (!m_mTable.isOpen()) return false; // Same Query if (!m_oldQuery.equals(m_query.getWhereClause())) return false; // Detail? if (!isDetail()) return true; // Same link column value String value = m_vo.ctx.getContext( m_vo.WindowNo, getLinkColumnName()); return m_linkValue.equals(value); } // isCurrent /** * Is the tab/table currently open * @return true if open */ public boolean isOpen() { // Open? if (m_mTable != null) return m_mTable.isOpen(); return false; } // isCurrent /** * Is Tab Incluced in other Tab * @return true if included */ public boolean isIncluded() { return m_included; } // isIncluded /** * Is Tab Incluced in other Tab * @param isIncluded true if included */ public void setIncluded(boolean isIncluded) { m_included = isIncluded; } // setIncluded /** * Get Only Current Days * @return history days */ public int getOnlyCurrentDays() { return m_vo.onlyCurrentDays; } // getOnlyCurrentDays /** * Return Parent ArrayList * @return parent column names */ public ArrayList<String> getParentColumnNames() { return m_parents; } // getParentColumnNames /** * Returns true if this is a detail record * @return true if not parent tab */ public boolean isDetail() { // We have IsParent columns and/or a link column if (m_parents.size() > 0 || m_vo.AD_Column_ID != 0) return true; return false; } // isDetail /** * Is Printed (Document can be printed) * @return true if printing */ public boolean isPrinted() { return m_vo.AD_Process_ID != 0; } // isPrinted /** * Get WindowNo * @return window no */ public int getWindowNo() { return m_vo.WindowNo; } // getWindowNo /** * Get TabNo * @return tab no */ public int getTabNo() { return m_vo.TabNo; } // getTabNo /** * Get Process ID * @return Process ID */ public int getAD_Process_ID() { return m_vo.AD_Process_ID; } // getAD_Process_ID /** * Is High Volume? * @return true if high volume table */ public boolean isHighVolume() { return m_vo.IsHighVolume; } // isHighVolume /** * Is Read Only? * @return true if read only */ public boolean isReadOnly() { if (m_vo.IsReadOnly) return true; // no restrictions if (m_vo.ReadOnlyLogic == null || m_vo.ReadOnlyLogic.equals("")) return m_vo.IsReadOnly; // ** dynamic content ** uses get_ValueAsString boolean retValue = Evaluator.evaluateLogic(this, m_vo.ReadOnlyLogic); log.finest(m_vo.Name + " (" + m_vo.ReadOnlyLogic + ") => " + retValue); return retValue; } // isReadOnly /** * Tab contains Always Update Field * @return true if field with always updateable */ public boolean isAlwaysUpdateField() { for (int i = 0; i < m_mTable.getColumnCount(); i++) { GridField field = m_mTable.getField(i); if (field.isAlwaysUpdateable()) return true; } return false; } // isAlwaysUpdateField /** * Can we Insert Records? * @return true not read only and allowed */ public boolean isInsertRecord() { if (isReadOnly()) return false; return m_vo.IsInsertRecord; } // isInsertRecord /** * Is the Tab Visible. * Called when constructing the window. * @param initialSetup return false only if not to be displayed * @return true, if displayed */ public boolean isDisplayed (boolean initialSetup) { // no restrictions String dl = m_vo.DisplayLogic; if (dl == null || dl.equals("")) return true; if (initialSetup) { if (dl.indexOf("@#") != -1) // global variable { String parsed = Env.parseContext (m_vo.ctx, 0, dl, false, false).trim(); if (parsed.length() != 0) // variable defined return Evaluator.evaluateLogic(this, dl); } return true; } // boolean retValue = Evaluator.evaluateLogic(this, dl); log.config(m_vo.Name + " (" + dl + ") => " + retValue); return retValue; } // isDisplayed /** * Get Variable Value (Evaluatee) * @param variableName name * @return value */ public String get_ValueAsString (String variableName) { return m_vo.ctx.getContext(m_vo.WindowNo, variableName, true); } // get_ValueAsString /** * Is Single Row * @return true if single row */ public boolean isSingleRow() { return m_vo.IsSingleRow; } // isSingleRow; /** * Set Single Row. * Temporary store of current value * @param isSingleRow toggle */ public void setSingleRow (boolean isSingleRow) { m_vo.IsSingleRow = isSingleRow; } // setSingleRow /** * Has Tree * @return true if tree exists */ public boolean isTreeTab() { return m_vo.HasTree; } // isTreeTab /** * Get Tab ID * @return Tab ID */ public int getAD_Tab_ID() { return m_vo.AD_Tab_ID; } // getAD_Tab_ID /** * Get Table ID * @return Table ID */ public int getAD_Table_ID() { return m_vo.AD_Table_ID; } // getAD_Table_ID /** * Get Window ID * @return Window ID */ public int getAD_Window_ID() { return m_vo.AD_Window_ID; } // getAD_Window_ID /** * Get Included Tab ID * @return Included_Tab_ID */ public int getIncluded_Tab_ID() { return m_vo.Included_Tab_ID; } // getIncluded_Tab_ID /** * Get TableName * @return Table Name */ public String getTableName() { return m_vo.TableName; } // getTableName /** * Get Tab Where Clause * @return where clause */ public String getWhereClause() { return m_vo.WhereClause; } // getWhereClause /** * Is Sort Tab * @return true if sort tab */ public boolean isSortTab() { return m_vo.IsSortTab; } // isSortTab /** * Get Order column for sort tab * @return AD_Column_ID */ public int getAD_ColumnSortOrder_ID() { return m_vo.AD_ColumnSortOrder_ID; } // getAD_ColumnSortOrder_ID /** * Get Yes/No column for sort tab * @return AD_Column_ID */ public int getAD_ColumnSortYesNo_ID() { return m_vo.AD_ColumnSortYesNo_ID; } // getAD_ColumnSortYesNo_ID /************************************************************************** * Get extended Where Clause (parent link) * @return parent link */ public String getWhereExtended() { return m_extendedWhere; } // getWhereExtended /** * Get Order By Clause * @param onlyCurrentDays only current rows * @return Order By Clause */ private String getOrderByClause(int onlyCurrentDays) { // First Prio: Tab Order By if (m_vo.OrderByClause.length() > 0) return m_vo.OrderByClause; // Second Prio: Fields (save it) m_vo.OrderByClause = ""; for (int i = 0; i < 3; i++) { String order = m_OrderBys[i]; if (order != null && order.length() > 0) { if (m_vo.OrderByClause.length() > 0) m_vo.OrderByClause += ","; m_vo.OrderByClause += order; } } if (m_vo.OrderByClause.length() > 0) return m_vo.OrderByClause; // Third Prio: onlyCurrentRows m_vo.OrderByClause = "Created"; if (onlyCurrentDays > 0) m_vo.OrderByClause += " DESC"; return m_vo.OrderByClause; } // getOrderByClause /************************************************************************** * Transaction support. * Depending on Table returns transaction info * @return info */ public String getTrxInfo() { // InvoiceBatch if (m_vo.TableName.startsWith("C_InvoiceBatch")) { int Record_ID = m_vo.ctx.getContextAsInt( m_vo.WindowNo, "C_InvoiceBatch_ID"); log.fine(m_vo.TableName + " - " + Record_ID); MessageFormat mf = null; try { mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "InvoiceBatchSummary")); } catch (Exception e) { log.log(Level.SEVERE, "InvoiceBatchSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "InvoiceBatchSummary"), e); } if (mf == null) return " "; /********************************************************************** * ** Message: ExpenseSummary ** * {0} Line(s) {1,number,#,##0.00} - Total: {2,number,#,##0.00} * * {0} - Number of lines * {1} - Toral * {2} - Currency */ Object[] arguments = new Object[3]; boolean filled = false; // String sql = "SELECT COUNT(*), NVL(SUM(LineNetAmt),0), NVL(SUM(LineTotalAmt),0) " + "FROM C_InvoiceBatchLine " + "WHERE C_InvoiceBatch_ID=? AND IsActive='Y'"; // try { PreparedStatement pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, Record_ID); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { // {0} - Number of lines Integer lines = new Integer(rs.getInt(1)); arguments[0] = lines; // {1} - Line net Double net = new Double(rs.getDouble(2)); arguments[1] = net; // {2} - Line net Double total = new Double(rs.getDouble(3)); arguments[2] = total; filled = true; } rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + sql, e); } if (filled) return mf.format (arguments); return " "; } // InvoiceBatch // Order || Invoice else if (m_vo.TableName.startsWith("C_Order") || m_vo.TableName.startsWith("C_Invoice")) { int Record_ID; boolean isOrder = m_vo.TableName.startsWith("C_Order"); // StringBuffer sql = new StringBuffer("SELECT COUNT(*) AS Lines,c.ISO_Code,o.TotalLines,o.GrandTotal," + "currencyBase(o.GrandTotal,o.C_Currency_ID,o.DateAcct, o.AD_Client_ID,o.AD_Org_ID) AS ConvAmt "); if (isOrder) { Record_ID = m_vo.ctx.getContextAsInt( m_vo.WindowNo, "C_Order_ID"); sql.append("FROM C_Order o" + " INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)" + " INNER JOIN C_OrderLine l ON (o.C_Order_ID=l.C_Order_ID) " + "WHERE o.C_Order_ID=? "); } else { Record_ID = m_vo.ctx.getContextAsInt( m_vo.WindowNo, "C_Invoice_ID"); sql.append("FROM C_Invoice o" + " INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)" + " INNER JOIN C_InvoiceLine l ON (o.C_Invoice_ID=l.C_Invoice_ID) " + "WHERE o.C_Invoice_ID=? "); } sql.append("GROUP BY o.C_Currency_ID, c.ISO_Code, o.TotalLines, o.GrandTotal, o.DateAcct, o.AD_Client_ID, o.AD_Org_ID"); log.fine(m_vo.TableName + " - " + Record_ID); MessageFormat mf = null; MessageFormat mfMC = null; try { mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "OrderSummary")); mfMC = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "OrderSummaryMC")); } catch (Exception e) { log.log(Level.SEVERE, "OrderSummary/MC", e); } if (mf == null || mfMC == null) return " "; /********************************************************************** * ** Message: OrderSummary/MC ** * {0} Line(s) - {1,number,#,##0.00} - Total: {3}{2,number,#,##0.00} = {5}{4,number,#,##0.00} * {0} Line(s) - {1,number,#,##0.00} - Total: {3}{2,number,#,##0.00} * * {0} - Number of lines * {1} - Line toral * {2} - Grand total (including tax, etc.) * {3} - Source Currency * (4) - Grand total converted to local currency * {5} - Base Currency */ Object[] arguments = new Object[6]; boolean filled = false; // try { PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null); pstmt.setInt(1, Record_ID); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { // {0} - Number of lines Integer lines = new Integer(rs.getInt(1)); arguments[0] = lines; // {1} - Line toral Double lineTotal = new Double(rs.getDouble(3)); arguments[1] = lineTotal; // {2} - Grand total (including tax, etc.) Double grandTotal = new Double(rs.getDouble(4)); arguments[2] = grandTotal; // {3} - Currency String currency = rs.getString(2); arguments[3] = currency; // (4) - Grand total converted to Base Double grandBase = new Double(rs.getDouble(5)); arguments[4] = grandBase; arguments[5] = m_vo.ctx.getContext("$CurrencyISO"); filled = true; } rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + sql, e); } if (filled) { if (arguments[2].equals(arguments[4])) return mf.format (arguments); else return mfMC.format (arguments); } return " "; } // Order || Invoice // Expense Report else if (m_vo.TableName.startsWith("S_TimeExpense") && m_vo.TabNo == 0) { int Record_ID = m_vo.ctx.getContextAsInt( m_vo.WindowNo, "S_TimeExpense_ID"); log.fine(m_vo.TableName + " - " + Record_ID); MessageFormat mf = null; try { mf = new MessageFormat(Msg.getMsg(Env.getAD_Language(m_vo.ctx), "ExpenseSummary")); } catch (Exception e) { log.log(Level.SEVERE, "ExpenseSummary=" + Msg.getMsg(Env.getAD_Language(m_vo.ctx), "ExpenseSummary"), e); } if (mf == null) return " "; /********************************************************************** * ** Message: ExpenseSummary ** * {0} Line(s) - Total: {1,number,#,##0.00} {2} * * {0} - Number of lines * {1} - Toral * {2} - Currency */ Object[] arguments = new Object[3]; boolean filled = false; // String SQL = "SELECT COUNT(*) AS Lines, SUM(ConvertedAmt*Qty) " + "FROM S_TimeExpenseLine " + "WHERE S_TimeExpense_ID=?"; // try { PreparedStatement pstmt = DB.prepareStatement(SQL, null); pstmt.setInt(1, Record_ID); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { // {0} - Number of lines Integer lines = new Integer(rs.getInt(1)); arguments[0] = lines; // {1} - Line toral Double total = new Double(rs.getDouble(2)); arguments[1] = total; // {3} - Currency arguments[2] = " "; filled = true; } rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, m_vo.TableName + "\nSQL=" + SQL, e); } if (filled) return mf.format (arguments); return " "; } // S_TimeExpense // Default - No Trx Info return null; } // getTrxInfo /************************************************************************** * Load Attachments for this table */ public void loadAttachments() { log.fine("#" + m_vo.TabNo); if (!canHaveAttachment()) return; String SQL = "SELECT AD_Attachment_ID, Record_ID FROM AD_Attachment " + "WHERE AD_Table_ID=?"; try { if (m_Attachments == null) m_Attachments = new HashMap<Integer,Integer>(); else m_Attachments.clear(); PreparedStatement pstmt = DB.prepareStatement(SQL, null); pstmt.setInt(1, m_vo.AD_Table_ID); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { Integer key = new Integer(rs.getInt(2)); Integer value = new Integer(rs.getInt(1)); m_Attachments.put(key, value); } rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, "loadAttachments", e); } log.config("#" + m_Attachments.size()); } // loadAttachment /** * Can this tab have Attachments?. * <p> * It can have an attachment if it has a key column ending with _ID. * The key column is empty, if there is no single identifying key. * @return true if record can have attachment */ public boolean canHaveAttachment() { if (getKeyColumnName().endsWith("_ID")) return true; return false; } // canHaveAttachment /** * Returns true, if current row has an Attachment * @return true if record has attchment */ public boolean hasAttachment() { if (m_Attachments == null) loadAttachments(); if (m_Attachments == null || m_Attachments.isEmpty()) return false; // Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); return m_Attachments.containsKey(key); } // hasAttachment /** * Get Attachment_ID for current record. * @return ID or 0, if not found */ public int getAD_AttachmentID() { if (m_Attachments == null) loadAttachments(); if (m_Attachments.isEmpty()) return 0; // Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); Integer value = (Integer)m_Attachments.get(key); if (value == null) return 0; else return value.intValue(); } // getAttachmentID /************************************************************************** * Load Chats for this table */ public void loadChats() { log.fine("#" + m_vo.TabNo); if (!canHaveAttachment()) return; String sql = "SELECT CM_Chat_ID, Record_ID FROM CM_Chat " + "WHERE AD_Table_ID=?"; try { if (m_Chats == null) m_Chats = new HashMap<Integer,Integer>(); else m_Chats.clear(); PreparedStatement pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, m_vo.AD_Table_ID); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { Integer key = new Integer(rs.getInt(2)); // Record_ID Integer value = new Integer(rs.getInt(1)); // CM_Chat_ID m_Chats.put(key, value); } rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, sql, e); } log.config("#" + m_Chats.size()); } // loadChats /** * Returns true, if current row has a Chat * @return true if record has chat */ public boolean hasChat() { if (m_Chats == null) loadChats(); if (m_Chats == null || m_Chats.isEmpty()) return false; // Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); return m_Chats.containsKey(key); } // hasChat /** * Get Chat_ID for this record. * @return ID or 0, if not found */ public int getCM_ChatID() { if (m_Chats == null) loadChats(); if (m_Chats.isEmpty()) return 0; // Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); Integer value = (Integer)m_Chats.get(key); if (value == null) return 0; else return value.intValue(); } // getCM_ChatID /************************************************************************** * Load Locks for Table and User */ public void loadLocks() { int AD_User_ID = Env.getCtx().getAD_User_ID(); log.fine("#" + m_vo.TabNo + " - AD_User_ID=" + AD_User_ID); if (!canHaveAttachment()) return; String sql = "SELECT Record_ID " + "FROM AD_Private_Access " + "WHERE AD_User_ID=? AND AD_Table_ID=? AND IsActive='Y' " + "ORDER BY Record_ID"; try { if (m_Lock == null) m_Lock = new ArrayList<Integer>(); else m_Lock.clear(); PreparedStatement pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, AD_User_ID); pstmt.setInt(2, m_vo.AD_Table_ID); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { Integer key = new Integer(rs.getInt(1)); m_Lock.add(key); } rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, sql, e); } log.fine("#" + m_Lock.size()); } // loadLooks /** * Record Is Locked * @return true if locked */ public boolean isLocked() { if (!MRole.getDefault(m_vo.ctx, false).isPersonalLock()) return false; if (m_Lock == null) loadLocks(); if (m_Lock == null || m_Lock.isEmpty()) return false; // Integer key = new Integer(m_mTable.getKeyID (m_currentRow)); return m_Lock.contains(key); } // isLocked /** * Lock Record * @param ctx context * @param Record_ID id * @param lock true if lock, otherwise unlock */ public void lock (Ctx ctx, int Record_ID, boolean lock) { int AD_User_ID = ctx.getAD_User_ID(); log.fine("Lock=" + lock + ", AD_User_ID=" + AD_User_ID + ", AD_Table_ID=" + m_vo.AD_Table_ID + ", Record_ID=" + Record_ID); MPrivateAccess access = MPrivateAccess.get (ctx, AD_User_ID, m_vo.AD_Table_ID, Record_ID); if (access == null) access = new MPrivateAccess (ctx, AD_User_ID, m_vo.AD_Table_ID, Record_ID); access.setIsActive(lock); access.save(); // loadLocks(); } // lock /************************************************************************** * Data Status Listener from MTable. * - get raw info and add current row information * - update the current row * - redistribute (fire) Data Status event * @param e event */ public void dataStatusChanged (DataStatusEvent e) { log.fine("#" + m_vo.TabNo + " - " + e.toString()); int oldCurrentRow = e.getCurrentRow(); m_DataStatusEvent = e; // save it // when sorted set current row to 0 String msg = m_DataStatusEvent.getAD_Message(); if (msg != null && msg.equals("Sorted")) setCurrentRow(0, true); // set current row m_DataStatusEvent.setCurrentRow(m_currentRow); // Same row - update value if (oldCurrentRow == m_currentRow) { GridField field = m_mTable.getField(e.getChangedColumn()); if (field != null) { Object value = m_mTable.getValueAt(m_currentRow, e.getChangedColumn()); field.setValue(value, m_mTable.isInserting()); } } else // Redistribute Info with current row info fireDataStatusChanged(m_DataStatusEvent); // log.fine("dataStatusChanged #" + m_vo.TabNo + "- fini", e.toString()); } // dataStatusChanged /** * Inform Listeners and build WHO info * @param e event */ private void fireDataStatusChanged (DataStatusEvent e) { DataStatusListener[] listeners = m_listenerList.getListeners(DataStatusListener.class); if (listeners.length == 0) return; log.fine(e.toString()); // WHO Info if (e.getCurrentRow() >= 0) { e.Created = (Timestamp)getValue("Created"); e.CreatedBy = (Integer)getValue("CreatedBy"); e.Updated = (Timestamp)getValue("Updated"); e.UpdatedBy = (Integer)getValue("UpdatedBy"); e.Record_ID = getValue(m_keyColumnName); // Info StringBuffer info = new StringBuffer(getTableName()); // We have a key column if (m_keyColumnName != null && m_keyColumnName.length() > 0) { info.append(" - ") .append(m_keyColumnName).append("=").append(e.Record_ID); } else // we have multiple parents { for (int i = 0; i < m_parents.size(); i++) { String keyCol = (String)m_parents.get(i); info.append(" - ") .append(keyCol).append("=").append(getValue(keyCol)); } } e.Info = info.toString(); } e.setInserting(m_mTable.isInserting()); // Distribute/fire it for (int i = 0; i < listeners.length; i++) listeners[i].dataStatusChanged(e); // log.fine("fini - " + e.toString()); } // fireDataStatusChanged /** * Create and fire Data Status Error Event * @param AD_Message message * @param info info * @param isError if not true, it is a Warning */ protected void fireDataStatusEEvent(String AD_Message, String info, boolean isError) { m_mTable.fireDataStatusEEvent(AD_Message, info, isError); } // fireDataStatusEvent /** * Create and fire Data Status Error Event (from Error Log) * @param errorLog log */ protected void fireDataStatusEEvent (ValueNamePair errorLog) { if (errorLog != null) m_mTable.fireDataStatusEEvent(errorLog); } // fireDataStatusEvent /** * Get Current Row * @return current row */ public int getCurrentRow() { if (m_currentRow != verifyRow(m_currentRow)) setCurrentRow(m_mTable.getRowCount()-1, true); return m_currentRow; } // getCurrentRow /** * Get Current Table Key ID * @return Record_ID */ public int getRecord_ID() { return m_mTable.getKeyID(m_currentRow); } // getRecord_ID /** * Get Key ID of row * @param row row number * @return The Key ID of the row or -1 if not found */ public int getKeyID (int row) { return m_mTable.getKeyID (row); } // getCurrentKeyID /** * Get Current Table AD_Client_ID * @return AD_Client_ID or -1 if not found */ public int getAD_Client_ID() { Object oo = getValue("AD_Client_ID"); if (oo instanceof Integer) return (Integer)oo; return -1; } // getAD_Client_ID /** * Navigate absolute - goto Row - (zero based). * - does nothing, if in current row * - saves old row if required * @param targetRow target row * @return current row */ public int navigate (int targetRow) { // nothing to do if (targetRow == m_currentRow) return m_currentRow; log.info ("Row=" + targetRow); // Row range check int newRow = verifyRow(targetRow); // Check, if we have old uncommitted data m_mTable.dataSave(newRow, false); // new position int row = setCurrentRow(newRow, true); return row; } // navigate /** * Navigate relatively - i.e. plus/minus from current position * @param rowChange row change * @return current row */ public int navigateRelative (int rowChange) { return navigate (m_currentRow + rowChange); } // navigateRelative /** * Navigate to current now (reload) * @return current row */ public int navigateCurrent() { log.info("Row=" + m_currentRow); return setCurrentRow(m_currentRow, true); } // navigateCurrent /** * Row Range check * @param targetRow target row * @return checked row */ private int verifyRow (int targetRow) { int newRow = targetRow; // Table Open? if (!m_mTable.isOpen()) { log.severe ("Table not open"); return -1; } // Row Count int rows = getRowCount(); if (rows == 0) { log.fine("No Rows"); return -1; } if (newRow >= rows) { newRow = rows-1; log.fine("Set to max Row: " + newRow); } else if (newRow < 0) { newRow = 0; log.fine("Set to first Row"); } return newRow; } // verifyRow /** * Set current row and load data into fields. * If there is no row - load nulls * @param newCurrentRow new current row * @param fireEvents fire events * @return current row */ private int setCurrentRow (int newCurrentRow, boolean fireEvents) { int oldCurrentRow = m_currentRow; m_currentRow = verifyRow (newCurrentRow); log.fine("Row=" + m_currentRow + " - fire=" + fireEvents); // Update Field Values int size = m_mTable.getColumnCount(); for (int i = 0; i < size; i++) { GridField mField = m_mTable.getField(i); // get Value from Table if (m_currentRow >= 0) { Object value = m_mTable.getValueAt(m_currentRow, i); mField.setValue(value, m_mTable.isInserting()); // gwu: now always validated, not just when inserting mField.validateValue(); } else { // no rows - set to a reasonable value - not updateable // Object value = null; // if (mField.isKey() || mField.isParent() || mField.getColumnName().equals(m_linkColumnName)) // value = mField.getDefault(); mField.setValue(); } } if (!fireEvents) // prevents informing twice return m_currentRow; // inform VTable/.. -> rowChanged m_propertyChangeSupport.firePropertyChange(PROPERTY, oldCurrentRow, m_currentRow); // inform APanel/.. -> dataStatus with row updated if (m_DataStatusEvent == null) m_DataStatusEvent = new DataStatusEvent(this, getRowCount(), m_mTable.isInserting(), // changed Env.getCtx().isAutoCommit(m_vo.WindowNo), m_mTable.isInserting()); // m_DataStatusEvent.setCurrentRow(m_currentRow); String status = m_DataStatusEvent.getAD_Message(); if (status == null || status.length() == 0) m_DataStatusEvent.setInfo("NavigateOrUpdate", null, false,false); fireDataStatusChanged(m_DataStatusEvent); return m_currentRow; } // setCurrentRow /************************************************************************** * Get RowCount * @return row count */ public int getRowCount() { int count = m_mTable.getRowCount(); // Wait a bit if currently loading if (count == 0 && m_mTable.isLoading()) { try { Thread.sleep(100); // .1 sec } catch (InterruptedException e) {} count = m_mTable.getRowCount(); } return count; } // getRowCount /** * Get Column/Field Count * @return field count */ public int getFieldCount() { return m_mTable.getColumnCount(); } // getFieldCount /** * Get Field by index * @param index index * @return MField */ public GridField getField (int index) { return m_mTable.getField(index); } // getField /** * Find Column * @param columnName column * @return index of column/field */ public int findColumn (String columnName) { return m_mTable.findColumn(columnName); } // findColumn /** * Get Field by DB column name * @param columnName column name * @return MField */ public GridField getField (String columnName) { return m_mTable.getField(columnName); } // getField /** * Get all Fields * @return MFields */ public GridField[] getFields () { return m_mTable.getFields(); } // getField /** * Set New Value & call Callout * @param columnName database column name * @param value value * @return error message or "" */ public String setValue (String columnName, Object value) { if (columnName == null) return "NoColumn"; return setValue(m_mTable.getField(columnName), value); } // setValue /** * Set New Value & call Callout * @param field field * @param value value * @return error message or "" */ public String setValue (GridField field, Object value) { if (field == null) return "NoField"; log.fine(field.getColumnName() + "=" + value + " - Row=" + m_currentRow); int col = m_mTable.findColumn(field.getColumnName()); m_mTable.setValueAt(value, m_currentRow, col, false); // return processFieldChange (field); } // setValue /** * Is Processed * @return true if current record is processed */ public boolean isProcessed() { int index = m_mTable.findColumn("Processed"); if (index != -1) { Object oo = m_mTable.getValueAt(m_currentRow, index); if (oo instanceof String) return "Y".equals(oo); if (oo instanceof Boolean) return ((Boolean)oo).booleanValue(); } return "Y".equals(m_vo.ctx.getContext( m_vo.WindowNo, "Processed")); } // isProcessed /** * Process Field Change - evaluate Dependencies and process Callouts. * * called from MTab.setValue or GridController.dataStatusChanged * @param changedField changed field * @return error message or "" */ public String processFieldChange (GridField changedField) { processDependencies (changedField); return processCallout (changedField); } // processFieldChange /** * Evaluate Dependencies * @param changedField changed field */ private void processDependencies (GridField changedField) { String columnName = changedField.getColumnName(); // log.trace(log.l4_Data, "Changed Column", columnName); // when column name is not in list of DependentOn fields - fini if (!hasDependants(columnName)) return; // Get dependent MFields (may be because of display or dynamic lookup) ArrayList<GridField> list = getDependantFields(columnName); for (int i = 0; i < list.size(); i++) { GridField dependentField = (GridField)list.get(i); // log.trace(log.l5_DData, "Dependent Field", dependentField==null ? "null" : dependentField.getColumnName()); // if the field has a lookup if (dependentField != null && dependentField.getLookup() instanceof MLookup) { MLookup mLookup = (MLookup)dependentField.getLookup(); // log.trace(log.l6_Database, "Lookup Validation", mLookup.getValidation()); // if the lookup is dynamic (i.e. contains this columnName as variable) if (mLookup.getValidation().indexOf("@"+columnName+"@") != -1) { log.fine(columnName + " changed - " + dependentField.getColumnName() + " set to null"); // invalidate current selection setValue(dependentField, null); } } if (dependentField != null && dependentField.getLookup() instanceof MLocatorLookup) { // gwu: invalidate currently selected locator if any dependent fields changed MLocatorLookup locLookup = (MLocatorLookup) dependentField.getLookup(); int valueAsInt = 0; if( changedField.getValue() != null && changedField.getValue() instanceof Number ) valueAsInt = ((Number) changedField.getValue()).intValue(); if( columnName.equals( "M_Warehouse_ID" ) ) { locLookup.setOnly_Warehouse_ID( valueAsInt ); } if( columnName.equals( "M_Product_ID" ) ) { locLookup.setOnly_Product_ID( valueAsInt ); } locLookup.setOnly_Outgoing(Env.getCtx().isSOTrx(m_vo.WindowNo )); locLookup.refresh(); if( !locLookup.isValid( dependentField.getValue() ) ) setValue(dependentField, null); } } // for all dependent fields } // processDependencies /************************************************************************** * Process Callout(s). * <p> * The Callout is in the string of * "class.method;class.method;" * If there is no class name, i.e. only a method name, the class is regarded * as CalloutSystem. * The class needs to comply with the Interface Callout. * * For a limited time, the old notation of Sx_matheod / Ux_menthod is maintained. * * @param field field * @return error message or "" * @see org.compiere.model.Callout */ private String processCallout (GridField field) { String callout = field.getCallout(); if (callout.length() == 0) return ""; // if (isProcessed()) // only active records return ""; // "DocProcessed"; Object value = field.getValue(); Object oldValue = field.getOldValue(); log.fine(field.getColumnName() + "=" + value + " (" + callout + ") - old=" + oldValue); StringTokenizer st = new StringTokenizer(callout, ";,", false); while (st.hasMoreTokens()) // for each callout { String cmd = st.nextToken().trim(); Callout call = null; String method = null; int methodStart = cmd.lastIndexOf("."); try { if (methodStart != -1) // no class { Class<?> cClass = Class.forName(cmd.substring(0,methodStart)); call = (Callout)cClass.newInstance(); method = cmd.substring(methodStart+1); } } catch (Exception e) { log.log(Level.SEVERE, "class", e); return "Callout Invalid: " + cmd + " (" + e.toString() + ")"; } if (call == null || method == null || method.length() == 0) return "Callout Invalid: " + method; String retValue = ""; try { retValue = call.start(m_vo.ctx, method, m_vo.WindowNo, this, field, value, oldValue); } catch (Exception e) { log.log(Level.SEVERE, "start", e); retValue = "Callout Invalid: " + e.toString(); return retValue; } if (!retValue.equals("")) // interrupt on first error { log.warning (retValue); return retValue; } } // for each callout return ""; } // processCallout /** * Get Value of Field with columnName * @param columnName column name * @return value */ public Object getValue (String columnName) { if (columnName == null) return null; GridField field = m_mTable.getField(columnName); return getValue(field); } // getValue /** * Get Value of Field * @param field field * @return value */ public Object getValue (GridField field) { if (field == null) return null; return field.getValue(); } // getValue /** * Get Value of Field in row * @param row row * @param columnName column name * @return value */ public Object getValue (int row, String columnName) { int col = m_mTable.findColumn(columnName); if (col == -1) return null; return m_mTable.getValueAt(row, col); } // getValue /** * toString * @return String representation */ public String toString() { String retValue = "MTab #" + m_vo.TabNo; if (m_vo != null) { retValue += " " + m_vo.Name + " (" + m_vo.AD_Tab_ID + ") QueryActive=" + (m_query != null && m_query.isActive()) + ", CurrentDays=" + m_vo.onlyCurrentDays; } return retValue; } // toString /************************************************************************** * @param l listener */ public synchronized void removePropertyChangeListener(PropertyChangeListener l) { m_propertyChangeSupport.removePropertyChangeListener(l); } /** * @param l listener */ public synchronized void addPropertyChangeListener(PropertyChangeListener l) { m_propertyChangeSupport.addPropertyChangeListener(l); } /** * @param l listener */ public synchronized void removeDataStatusListener(DataStatusListener l) { m_listenerList.remove(DataStatusListener.class, l); } /** * @param l listener */ public synchronized void addDataStatusListener(DataStatusListener l) { m_listenerList.add(DataStatusListener.class, l); } } // MTab

The table below shows all metrics for GridTab.java.

MetricValueDescription
BLOCKS231.00Number of blocks
BLOCK_COMMENT 0.00Number of block comment lines
COMMENTS750.00Comment lines
COMMENT_DENSITY 0.64Comment density
COMPARISONS206.00Number of comparison operators
CYCLOMATIC338.00Cyclomatic complexity
DECL_COMMENTS131.00Comments in declarations
DOC_COMMENT623.00Number of javadoc comment lines
ELOC1169.00Effective lines of code
EXEC_COMMENTS131.00Comments in executable code
EXITS206.00Procedure exits
FUNCTIONS111.00Number of function declarations
HALSTEAD_DIFFICULTY99.30Halstead difficulty
HALSTEAD_EFFORT 0.00Halstead effort
INTERFACE_COMPLEXITY245.00Interface complexity
JAVA0001 0.00JAVA0001 Package name does not contain only lower case letters
JAVA0002 0.00JAVA0002 Package name does not begin with a top level domain name or country code
JAVA0003 1.00JAVA0003 Minimize use of on-demand (.*) imports
JAVA0004 0.00JAVA0004 Unnecessary import from java.lang
JAVA0005 0.00JAVA0005 Imports not in specified order
JAVA0006 0.00JAVA0006 Empty finally block
JAVA0007 0.00JAVA0007 Should not declare public field
JAVA0008 1.00JAVA0008 Empty catch block
JAVA0009 0.00JAVA0009 Protected member in final class
JAVA0010 0.00JAVA0010 Non-instantiable class does not contain a non-private static member
JAVA0011 0.00JAVA0011 Abstract class does not contain an abstract method
JAVA0012 0.00JAVA0012 Non-constructor method with same name as declaring class
JAVA0013 0.00JAVA0013 Non-blank final field is not static
JAVA0014 0.00JAVA0014 Class with only static members has non-private constructor
JAVA0015 0.00JAVA0015 Package class contains public nested type
JAVA0016 0.00JAVA0016 Abstract class contains public constructor
JAVA0017 0.00JAVA0017 Class name does not have required form
JAVA0018 0.00JAVA0018 Method name does not have required form
JAVA0019 0.00JAVA0019 Interface name does not have required form
JAVA0020 0.00JAVA0020 Field name does not have required form
JAVA0021 0.00JAVA0021 Interface method name does not have required form
JAVA0022 0.00JAVA0022 Static final field name does not have required form
JAVA0023 0.00JAVA0023 Empty finalize method
JAVA0024 0.00JAVA0024 Empty class
JAVA0025 0.00JAVA0025 Method override is empty
JAVA0026 0.00JAVA0026 Finalize method with parameters
JAVA0029 0.00JAVA0029 Private method not used
JAVA0030 0.00JAVA0030 Private field not used
JAVA0031 0.00JAVA0031 Case statement not properly closed
JAVA0032 0.00JAVA0032 Switch statement missing default
JAVA0033 0.00JAVA0033 default: not last case in switch statement
JAVA0034115.00JAVA0034 Missing braces in if statement
JAVA0035 4.00JAVA0035 Missing braces in for statement
JAVA0036 0.00JAVA0036 Missing braces in while statement
JAVA0038 0.00JAVA0038 Non-case label in switch statement
JAVA0039 0.00JAVA0039 Break statement with label
JAVA0040 0.00JAVA0040 Switch statement contains N cases (maximum: M)
JAVA0041 0.00JAVA0041 Nested synchronized block
JAVA0042 0.00JAVA0042 Empty synchronized statement
JAVA0043 0.00JAVA0043 Inner class does not use outer class
JAVA0044 0.00JAVA0044 Serializable class with no instance variables
JAVA0045 0.00JAVA0045 Serializable class with only transient fields
JAVA0046 0.00JAVA0046 Name of class not derived from Exception ends with 'Exception'
JAVA0047 0.00JAVA0047 Serializable class derives from invalid base class
JAVA0048 0.00JAVA0048 Name of class derived from Exception does not end with 'Exception'
JAVA0049 0.00JAVA0049 Nested block at depth N (maximum: M)
JAVA0050 0.00JAVA0050 Class derives from java.lang.Error
JAVA0051 0.00JAVA0051 Class derives from java.lang.RuntimeException
JAVA0052 0.00JAVA0052 Class derives from java.lang.Throwable
JAVA0053 0.00JAVA0053 Unused label
JAVA0054 0.00JAVA0054 Inheritance depth N exceeds maximum M
JAVA0055 0.00JAVA0055 Class should be interface
JAVA0056 0.00JAVA0056 Unnecessary abstract modifier for interface or annotation
JAVA0057 0.00JAVA0057 Unnecessary default constructor
JAVA0058 0.00JAVA0058 Constructor calls super()
JAVA0059 0.00JAVA0059 Method override only calls super()
JAVA0061 0.00JAVA0061 Inaccessible member in anonymous class
JAVA0062 0.00JAVA0062 Public class missing public member or protected constructor
JAVA0063 0.00JAVA0063 Identifier name should not contain '$'
JAVA0064 1.00JAVA0064 N variations of identifier name (maximum: M)
JAVA0065 0.00JAVA0065 Unnecessary final modifier for method in final class
JAVA0066 0.00JAVA0066 Unnecessary modifier for interface nested type
JAVA0067 0.00JAVA0067 Array descriptor on identifier name
JAVA0068 0.00JAVA0068 Modifiers not declared in recommended order
JAVA0071 0.00JAVA0071 Strings compared with ==
JAVA0073 0.00JAVA0073 Integer division in floating-point context
JAVA0074 0.00JAVA0074 Use of Object.notify()
JAVA0075 0.00JAVA0075 Method parameter hides field
JAVA0076 0.00JAVA0076 Use of magic number
JAVA0077 0.00JAVA0077 Private field not used in declaring class
JAVA0078 0.00JAVA0078 Floating point values compared with ==
JAVA0079 0.00JAVA0079 Use of instance to reference static member
JAVA0080 0.00JAVA0080 Import declaration not used
JAVA0081 0.00JAVA0081 Boolean literal in comparison
JAVA0082 5.00JAVA0082 Unnecessary widening cast
JAVA0083 0.00JAVA0083 Unnecessary instanceof test
JAVA0084 0.00JAVA0084 Should use compound assignment operator
JAVA0085 0.00JAVA0085 Use of sun.* class
JAVA0087 1.00JAVA0087 Use of Thread.sleep()
JAVA0089 0.00JAVA0089 Use of restricted package
JAVA0092 0.00JAVA0092 Use of restricted type
JAVA0093 0.00JAVA0093 Redundant assignment
JAVA0094 0.00JAVA0094 Field hides a superclass field
JAVA0095 0.00JAVA0095 Uninitialized private field
JAVA0096 0.00JAVA0096 Field in nested class hides outer field
JAVA0098 0.00JAVA0098 Minimize use of implicit field initializers
JAVA0100 1.00JAVA0100 Class contains N non-final fields (maximum: M)
JAVA0101 0.00JAVA0101 Unnecessary modifier for field in interface
JAVA0102 0.00JAVA0102 Last statement in finalize() not super.finalize()
JAVA0103 0.00JAVA0103 Explicit call to finalize()
JAVA0104 0.00JAVA0104 finalize() only calls super.finalize()
JAVA0105 0.00JAVA0105 Duplicate import declaration
JAVA0106 0.00JAVA0106 Unnecessary import from current package
JAVA0108 0.00JAVA0108 Incorrect javadoc: no @param tag for 'parameter'
JAVA0109 0.00JAVA0109 Incorrect javadoc: no parameter 'parameter'
JAVA0110 0.00JAVA0110 Incorrect javadoc: no @return tag
JAVA0111 0.00JAVA0111 Incorrect javadoc: @return tag for void method
JAVA0112 0.00JAVA0112 Incorrect javadoc: no exception 'exception' in throws
JAVA0113 0.00JAVA0113 Incorrect javadoc: no @author tag
JAVA0114 0.00JAVA0114 Incorrect javadoc: no @version tag
JAVA0115 0.00JAVA0115 Incorrect javadoc: no @throws or @exception tag for 'exception'
JAVA0116 0.00JAVA0116 Missing javadoc: field 'field'
JAVA0117 0.00JAVA0117 Missing javadoc: method 'method'
JAVA0118 0.00JAVA0118 Missing javadoc: type 'type'
JAVA0119 0.00JAVA0119 Control variable changed within body of for loop
JAVA0123 0.00JAVA0123 Use all three components of for loop
JAVA0125 0.00JAVA0125 Continue statement with label
JAVA0126 0.00JAVA0126 Method declares unchecked exception in throws
JAVA0128 0.00JAVA0128 Public constructor in non-public class
JAVA0130 0.00JAVA0130 Non-static method does not use instance fields
JAVA0131 0.00JAVA0131 Compatible method does not override base
JAVA0132 0.00JAVA0132 Method overload with compatible signature
JAVA0133 0.00JAVA0133 Non-synchronized method overrides synchronized method
JAVA0135 0.00JAVA0135 Only one of Object.equals and Object.hashCode defined: missing 'method'
JAVA0136 1.00JAVA0136 N methods defined in class (maximum: M)
JAVA0137 0.00JAVA0137 Non-abstract class missing constructor
JAVA0138 0.00JAVA0138 N parameters defined for method (maximum: M)
JAVA0139 0.00JAVA0139 Definition of main other than public static void main(java.lang.String[])
JAVA0141 0.00JAVA0141 Unnecessary modifier for method in interface
JAVA0143 4.00JAVA0143 Synchronized method
JAVA0144 0.00JAVA0144 Line exceeds maximum M characters
JAVA01455231.00JAVA0145 Tab character used in source file
JAVA0150 0.00JAVA0150 java.lang.Error (or subclass) thrown
JAVA0153 0.00JAVA0153 Inefficient conversion of integer to string
JAVA0159 0.00JAVA0159 Inefficient conversion of string to integer
JAVA0160 0.00JAVA0160 Method does not throw specified exception
JAVA0161 0.00JAVA0161 Conditional wait() not in loop
JAVA0163 1.00JAVA0163 Empty statement
JAVA0165 0.00JAVA0165 Conflicting return statement in finally block
JAVA0166 6.00JAVA0166 Generic exception caught
JAVA0167 0.00JAVA0167 ThreadDeath not rethrown
JAVA0169 0.00JAVA0169 Unnecessary catch block: exception 'exception'
JAVA0170 0.00JAVA0170 Caught exception not derived from java.lang.Exception
JAVA0171 0.00JAVA0171 Unused local variable
JAVA0173 0.00JAVA0173 Unused method parameter
JAVA0174 0.00JAVA0174 Assigned local variable never used
JAVA0175 0.00JAVA0175 Successive assignment to variable
JAVA0176 0.00JAVA0176 Local variable name does not have required form
JAVA0177 1.00JAVA0177 Variable declaration missing initializer
JAVA0179 0.00JAVA0179 Local variable hides visible field
JAVA0233 0.00JAVA0233 Definition of serialVersionUID other than 'private static final long serialVersionUID'
JAVA0234 0.00JAVA0234 Class is Serializable but does not define serialVersionUID
JAVA0235 0.00JAVA0235 Class defines serialVersionUID but does not implement Serializable
JAVA0236 0.00JAVA0236 Attempt to clone an object which does not implement Cloneable
JAVA0237 0.00JAVA0237 Class implements Cloneable but does not have public clone method
JAVA0238 0.00JAVA0238 Clone method does not call super.clone()
JAVA0239 0.00JAVA0239 Class declares 'readObject' or 'writeObject' but does not implement Serializable
JAVA0240 0.00JAVA0240 Serializable class which declares readObject or writeObject but not both
JAVA0241 0.00JAVA0241 'readObject' or 'writeObject' should be declared private in Serializable class
JAVA0242 0.00JAVA0242 Transient field in non-Serializable class
JAVA0243 0.00JAVA0243 'readResolve' or 'writeReplace' should be declared private or protected
JAVA0244 0.00JAVA0244 Field or method name in subclass differs only by case from inherited field or method
JAVA0245 0.00JAVA0245 JUnit TestCase with non-trivial constructor
JAVA0246 0.00JAVA0246 JUnit assertXXX statement missing message parameter
JAVA0247 0.00JAVA0247 JUnit 'setUp()' and 'tearDown()' should call super method
JAVA0248 0.00JAVA0248 JUnit method 'setUp' or 'tearDown' with incorrect signature
JAVA0249 0.00JAVA0249 JUnit TestCase 'suite()' should be declared static
JAVA0250 0.00JAVA0250 JUnit TestCase declares testXXX method with incorrect signature
JAVA0251 0.00JAVA0251 Use '%n' for line breaks in printf/format for platform independence
JAVA0252 0.00JAVA0252 'enum' is a Java 1.5 reserved word
JAVA0253 0.00JAVA0253 Not all enum constants consumed in switch statement
JAVA0254 0.00JAVA0254 Use enhanced for loop construct instead of Iterator
JAVA0255 0.00JAVA0255 Result of method invocation not used
JAVA0256 0.00JAVA0256 Assignment of external collection/array to field
JAVA0257 0.00JAVA0257 Use of 'Constant Interface' anti-pattern
JAVA0258 0.00JAVA0258 Implement Iterable for foreach compatibility
JAVA0259 1.00JAVA0259 Return of collection/array field
JAVA0260 0.00JAVA0260 Use 'enum' instead of Enumerated Type pattern
JAVA0261 0.00JAVA0261 Use specialized Enum collection types
JAVA0262 0.00JAVA0262 Use of char in integer context
JAVA0263 0.00JAVA0263 Long literal ends with 'l' instead of 'L'
JAVA0264 0.00JAVA0264 Integer math in long context - check for overflow
JAVA0265 0.00JAVA0265 Use of Throwable.printStackTrace()
JAVA0266 0.00JAVA0266 Use of System.out
JAVA0267 0.00JAVA0267 Use of System.err
JAVA0269 0.00JAVA0269 Contents of StringBuffer never used
JAVA0270 1.00JAVA0270 Use Java 5.0 enhanced for loop construct to iterate over all elements in an array
JAVA0271 0.00JAVA0271 Minimize use of on-demand (.*) static imports
JAVA0272 0.00JAVA0272 Thread.run() called
JAVA0273 0.00JAVA0273 Non-final derivative of Thread calls start() in constructor
JAVA0274 0.00JAVA0274 Serializable class has a synchronized readObject()
JAVA0275 0.00JAVA0275 Serializable class has a synchronized writeObject() and no other synchronized methods
JAVA0276 0.00JAVA0276 Unnecessary use of String constructor
JAVA0277 0.00JAVA0277 Iterator.next() implementation does not throw NoSuchElementException
JAVA0278 0.00JAVA0278 Unnecessary use of Boolean constructor
JAVA0279 0.00JAVA0279 Serialization method readObject or readObjectNoData calls an overridable method
JAVA0280 0.00JAVA0280 IllegalMonitorStateException caught
JAVA0281 0.00JAVA0281 Iterator.next() not called in loop
JAVA0282 0.00JAVA0282 Call to Iterator.next() in loop which does not test Iterator.hasNext()
JAVA0283 0.00JAVA0283 Control variable not updated in loop body
JAVA0284 0.00JAVA0284 Explicit garbage collection
JAVA0285 0.00JAVA0285 Dereference of potentially null variable
JAVA0286 0.00JAVA0286 Dereference of null variable
JAVA0287 4.00JAVA0287 Unnecessary null check
JAVA0288 0.00JAVA0288 Inconsistent null check
LINES2460.00Number of lines in the source file
LINE_COMMENT127.00Number of line comments
LOC1516.00Lines of code
LOGICAL_LINES669.00Number of statements
LOOPS16.00Number of loops
NEST_DEPTH 5.00Maximum nesting depth
OPERANDS3039.00Number of operands
OPERATORS5723.00Number of operators
PARAMS55.00Number of formal parameter declarations
PROGRAM_LENGTH8762.00Halstead program length
PROGRAM_VOCAB864.00Halstead program vocabulary
PROGRAM_VOLUME 0.00Halstead program volume
RETURNS190.00Number of return points from functions
SIZE65358.00Size of the file in bytes
UNIQUE_OPERANDS811.00Number of unique operands
UNIQUE_OPERATORS53.00Number of unique operators
WHITESPACE194.00Number of whitespace lines