⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlookup.java

📁 大家共享愉快, 共享愉快, 共享愉快, 共享愉快,共享愉快
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 * The contents of this file are subject to the   Compiere License  Version 1.1
 * ("License"); You may not use this file except in compliance with the License
 * You may obtain a copy of the License at http://www.compiere.org/license.html
 * Software distributed under the License is distributed on an  "AS IS"  basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * The Original Code is Compiere ERP & CRM Smart Business Solution. The Initial
 * Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke
 * are Copyright (C) 1999-2005 Jorg Janke.
 * All parts are Copyright (C) 1999-2005 ComPiere, Inc.  All Rights Reserved.
 * Contributor(s): ______________________________________.
 *****************************************************************************/
package org.compiere.model;

import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.logging.*;

import org.compiere.util.*;

/**
 *	An intelligent MutableComboBoxModel, which determines what can be cached.
 *  <pre>
 *      Validated   - SQL is final / not dynamic
 *      AllLoaded   - All Records are loaded
 *
 *		Get Info about Lookup
 *		-	SQL
 *		-	KeyColumn
 *		-	Zoom Target
 *  </pre>
 * 	@author 	Jorg Janke
 * 	@version 	$Id: MLookup.java,v 1.40 2006/01/19 01:51:20 jjanke Exp $
 */
public final class MLookup extends Lookup implements Serializable
{
	/**
	 *  MLookup Constructor
	 *  @param info info
	 *  @param TabNo tab no
	 */
	public MLookup (MLookupInfo info, int TabNo)
	{
		super(info.DisplayType, info.WindowNo);
		m_info = info;
		log.fine(m_info.KeyColumn);

		//  load into local lookup, if already cached
		if (MLookupCache.loadFromCache (m_info, m_lookup))
			return;

		//  Don't load Search or CreatedBy/UpdatedBy
		if (m_info.DisplayType == DisplayType.Search 
			|| m_info.IsCreadedUpdatedBy)
			return;
		//  Don't load Parents/Keys
		if (m_info.IsParent || m_info.IsKey)
		{
			m_hasInactive = true;		//	creates focus listener for dynamic loading
			return;						//	required when parent needs to be selected (e.g. price from product)
		}
		//
		m_loader = new MLoader();
	//	if (TabNo != 0)
	//		m_loader.setPriority(Thread.NORM_PRIORITY - 1);
		m_loader.start();
	//	m_loader.run();		//	test sync call
	}	//	MLookup

	/** Inactive Marker Start       */
	public static final String  INACTIVE_S = "~";
	/** Inactive Marker End         */
	public static final String  INACTIVE_E = "~";
	/** Number of max rows to load	*/
	private static final int	MAX_ROWS = 1000;		//	i.e. Drop Down has max 500 items
	/**	Indicator for Null			*/
	private static Integer 		MINUS_ONE = new Integer(-1);


	/** The Lookup Info Value Object        */
	private MLookupInfo         m_info = null;

	/** Storage of data  Key-NamePair	*/
	private volatile LinkedHashMap<Object,Object>	m_lookup = new LinkedHashMap<Object,Object>();
	/** The Data Loader                 */
	private MLoader				m_loader;
	//

	/** All Data loaded                 */
	private boolean             m_allLoaded = false;
	/** Inactive records exists         */
	private boolean 		    m_hasInactive = false;

	/*  Refreshing - disable cashing    */
	private boolean             m_refreshing = false;
	/** Next Read for Parent			*/
	private long				m_nextRead = 0;
	
	/**
	 *  Dispose
	 */
	public void dispose()
	{
		if (m_info != null)
			log.fine(m_info.KeyColumn + ": dispose");
		if (m_loader != null && m_loader.isAlive())
			m_loader.interrupt();
		m_loader = null;
		//
		if (m_lookup != null)
			m_lookup.clear();
		m_lookup = null;
		if (m_lookupDirect != null)
			m_lookupDirect.clear();
		m_lookupDirect = null;
		//
		m_info = null;
		//
		super.dispose();
	}   //  dispose

	/**
	 *  Wait until async Load Complete
	 */
	public void loadComplete()
	{
		if (m_loader != null && m_loader.isAlive())
		{
			try
			{
				m_loader.join();
				m_loader = null;
			}
			catch (InterruptedException ie)
			{
				log.log(Level.SEVERE, m_info.KeyColumn + ": Interrupted", ie);
			}
		}
	}   //  loadComplete

	/**
	 *	Get value (name) for key.
	 *  If not found return null;
	 *  @param key key	(Integer for Keys or String for Lists)
	 *  @return value
	 */
	public NamePair get (Object key)
	{
		if (key == null || MINUS_ONE.equals(key))	//	indicator for null
			return null;

		if (m_info.IsParent && m_nextRead < System.currentTimeMillis())
		{
			m_lookup.clear();
			if (m_lookupDirect != null)
				m_lookupDirect.clear();
			m_nextRead = System.currentTimeMillis() + 500;	//	1/2 sec
		}
		
		//	try cache
		NamePair retValue = (NamePair)m_lookup.get(key);
		if (retValue != null)
			return retValue;

		//	Not found and waiting for loader
		if (m_loader != null && m_loader.isAlive())
		{
			log.finer((m_info.KeyColumn==null ? "ID="+m_info.Column_ID : m_info.KeyColumn) + ": waiting for Loader");
			loadComplete();
			//	is most current
			retValue = (NamePair)m_lookup.get(key);
			if (retValue != null)
				return retValue;
		}

		//  Always check for parents - not if we SQL was validated and completely loaded
		if (!m_info.IsParent && m_info.IsValidated && m_allLoaded)
		{
			log.finer(m_info.KeyColumn + ": <NULL> - " + key // + "(" + key.getClass()
					+ "; Size=" + m_lookup.size());
		//	log.finest( m_lookup.keySet().toString(), "ContainsKey = " + m_lookup.containsKey(key));
			//  also for new values and inactive ones
			return getDirect(key, false, true);		//	cache locally    
		}

		log.finest (m_info.KeyColumn + ": " + key
				+ "; Size=" + m_lookup.size() + "; Validated=" + m_info.IsValidated
				+ "; All Loaded=" + m_allLoaded + "; HasInactive=" + m_hasInactive);
		//	never loaded
		if (!m_allLoaded 
			&& m_lookup.size() == 0 
			&& !m_info.IsCreadedUpdatedBy
			&& !m_info.IsParent
			&& m_info.DisplayType != DisplayType.Search)
		{
			m_loader = new MLoader();
			m_loader.run();		//	sync!
			retValue = (NamePair)m_lookup.get(key);
			if (retValue != null)
				return retValue;
		}
		//	Try to get it directly
		boolean cacheLocal = m_info.IsValidated ; 
		return getDirect(key, false, cacheLocal);	//	do NOT cache	
	}	//	get

	/**
	 *	Get Display value (name).
	 *  If not found return key embedded in inactive signs.
	 *  @param key key
	 *  @return value
	 */
	public String getDisplay (Object key)
	{
		if (key == null)
			return "";
		//
		Object display = get (key);
		if (display == null)
			return "<" + key.toString() + ">";
		return display.toString();
	}	//	getDisplay

	/**
	 *  The Lookup contains the key
	 *  @param key key
	 *  @return true if key is known
	 */
	public boolean containsKey (Object key)
	{
		return m_lookup.containsKey(key);
	}   //  containsKey

	/**
	 * @return  a string representation of the object.
	 */
	public String toString()
	{
		return "MLookup[" + m_info.KeyColumn + ",Column_ID=" + m_info.Column_ID
			+ ",Size=" + m_lookup.size() + ",Validated=" + isValidated()
			+ "-" + getValidation()
			+ "]";
	}	//	toString

	/**
	 * Indicates whether some other object is "equal to" this one.
	 * @param   obj   the reference object with which to compare.
	 * @return  <code>true</code> if this object is the same as the obj
	 *          argument; <code>false</code> otherwise.
	 */
	public boolean equals(Object obj)
	{
		if (obj instanceof MLookup)
		{
			MLookup ll = (MLookup)obj;
			if (ll.m_info.Column_ID == this.m_info.Column_ID)
				return true;
		}
		return false;
	}	//	equals

	/**
	 *	Return Size
	 *  @return size
	 */
	public int size()
	{
		return m_lookup.size();
	}	//	size

	/**
	 *	Is it all loaded
	 *  @return true, if all loaded
	 */
	public boolean isAllLoaded()
	{
		return m_allLoaded;
	}	//	isAllLoaded

	/**
	 *	Is the List fully Validated
	 *  @return true, if validated
	 */
	public boolean isValidated()
	{
		if (m_info == null)
			return false;
		return m_info.IsValidated;
	}	//	isValidated

	/**
	 *  Get Validation SQL
	 *  @return Validation SQL
	 */
	public String getValidation()
	{
		return m_info.ValidationCode;
	}   //  getValidation

	/**
	 *  Get Reference Value
	 *  @return Reference Value
	 */
	public int getAD_Reference_Value_ID()
	{
		return m_info.AD_Reference_Value_ID;
	}   //  getAD_Reference_Value_ID


	/**
	 *  Has inactive elements in list
	 *  @return true, if list contains inactive values
	 */
	public boolean hasInactive()
	{
		return m_hasInactive;
	}   //  hasInactive

	/**
	 *	Return info as ArrayList containing Value/KeyNamePair
	 *  @param onlyValidated only validated
	 * 	@param loadParent get Data even for parent lookups
	 *  @return List
	 */
	private ArrayList<Object> getData (boolean onlyValidated, boolean loadParent)
	{
		if (m_loader != null && m_loader.isAlive())
		{
			log.fine((m_info.KeyColumn==null ? "ID="+m_info.Column_ID : m_info.KeyColumn) + ": getData - waiting for Loader");
			loadComplete();
		}

		//	Never Loaded (correctly)
		if (!m_allLoaded || m_lookup.size() == 0)
			refresh (loadParent);

		//	already validation included
		if (m_info.IsValidated)
			return new ArrayList<Object>(m_lookup.values());

		if (!m_info.IsValidated && onlyValidated)
		{
			refresh (loadParent);
			log.fine(m_info.KeyColumn + ": getData Validated - #" + m_lookup.size());
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -