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

📄 settingmanager.java

📁 由国外的一个著名的geonetwork修改而来
💻 JAVA
字号:
//=============================================================================//===	Copyright (C) 2001-2005 Food and Agriculture Organization of the//===	United Nations (FAO-UN), United Nations World Food Programme (WFP)//===	and United Nations Environment Programme (UNEP)//===//===	This program is free software; you can redistribute it and/or modify//===	it under the terms of the GNU General Public License as published by//===	the Free Software Foundation; either version 2 of the License, or (at//===	your option) any later version.//===//===	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//===//===	Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,//===	Rome - Italy. email: GeoNetwork@fao.org//==============================================================================package org.fao.geonet.kernel.setting;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.StringTokenizer;import java.util.Vector;import java.util.concurrent.locks.ReentrantReadWriteLock;import jeeves.resources.dbms.Dbms;import jeeves.server.resources.ProviderManager;import jeeves.server.resources.ResourceListener;import jeeves.server.resources.ResourceProvider;import org.fao.geonet.constants.Geonet;import org.jdom.Element;//=============================================================================/** Allows hierarchical management of application settings. The settings API  * has been designed with the following goals:  *  * - speed: all the settings tree is kept into memory  *  * - transactional: changes follow the rules of transactions. The only issue  *                  is that changes are not visible until commit. If a thread  *                  changes a value and then reads it, the thread gets the old  *                  value. Added settings will not be visible and removed ones  *                  will still be visible until commit.  *  * - concurrent: many thread can access the settings API at the same time. A  *               read/write lock is used to arbitrate threads  *  * Multiple removes: there are no issues. If thread A removes a subtree S1 and  * another thread B removes a subtree S2 inside S1, the first thread to commit  * succeeds while the second always rises a 'cannot serializable exception'.  * In any commit combination, the settings integrity is maintained.  *  * Tree structure:  *  * + system  * |   + options  * |       + useProxy  * |           + host  * |           + port  * |  * + harvesting  */public class SettingManager{	private Setting root;	//---------------------------------------------------------------------------	//---	//--- Constructor	//---	//---------------------------------------------------------------------------	public SettingManager(Dbms dbms, ProviderManager provMan) throws SQLException	{		List list = dbms.select("SELECT * FROM Settings").getChildren();		root = new Setting(0, null, null);		createSubTree(root, list);		for(ResourceProvider rp : provMan.getProviders())			if (rp.getName().equals(Geonet.Res.MAIN_DB))				rp.addListener(resList);	}	//---------------------------------------------------------------------------	//---	//--- API methods	//---	//---------------------------------------------------------------------------	//---------------------------------------------------------------------------	//--- Getters	//---------------------------------------------------------------------------	public Element get(String path, int level)	{		lock.readLock().lock();		try		{			Setting s = resolve(path);			return (s == null) ? null : build(s, level);		}		finally		{			lock.readLock().unlock();		}	}	//---------------------------------------------------------------------------	public String getValue(String path)	{		lock.readLock().lock();		try		{			Setting s = resolve(path);			return (s == null) ? null : s.getValue();		}		finally		{			lock.readLock().unlock();		}	}	//---------------------------------------------------------------------------	//--- Setters	//---------------------------------------------------------------------------	public boolean setName(Dbms dbms, String path, String name) throws SQLException	{		if (path == null)			throw new IllegalArgumentException("Path cannot be null");		lock.writeLock().lock();		try		{			Setting s = resolve(path);			if (s == null)				return false;			execute(dbms, "UPDATE Settings SET name=? WHERE id=?", name, s.getId());			tasks.add(Task.getNameChangedTask(dbms, s, name));			return true;		}		finally		{			lock.writeLock().unlock();		}	}	//---------------------------------------------------------------------------	public boolean setValue(Dbms dbms, String path, Object value) throws SQLException	{		Map<String, Object> values = new HashMap<String, Object>();		values.put(path, value);		return setValues(dbms, values);	}	//---------------------------------------------------------------------------	public boolean setValues(Dbms dbms, Map<String, Object> values) throws SQLException	{		lock.writeLock().lock();		try		{			boolean success = true;			for(Map.Entry<String, Object> entry : values.entrySet())			{				String path = entry.getKey();				String value= makeString(entry.getValue());				Setting s = resolve(path);				if (s == null)					success = false;				else				{					execute(dbms, "UPDATE Settings SET value=? WHERE id=?", value, s.getId());					tasks.add(Task.getValueChangedTask(dbms, s, value));				}			}			return success;		}		finally		{			lock.writeLock().unlock();		}	}	//---------------------------------------------------------------------------	/** When adding to a newly created node, path must be 'id:...'	  */	public String add(Dbms dbms, String path, Object name, Object value) throws SQLException	{		if (name == null)			throw new IllegalArgumentException("Name cannot be null");		String sName  = makeString(name);		String sValue = makeString(value);		lock.writeLock().lock();		try		{			//--- first, we look into the tasks list because the 'id' could have been			//--- added just now			Setting parent = findAmongAdded(dbms, path);			//--- if we fail, just do a normal search			if (parent == null)				parent = resolve(path);			if (parent == null)					return null;			Setting child = new Setting(getNextSerial(dbms), sName, sValue);			String query = "INSERT INTO Settings(id, parentId, name, value) VALUES(?, ?, ?, ?)";			execute(dbms, query, child.getId(), parent.getId(), sName, sValue);			tasks.add(Task.getAddedTask(dbms, parent, child));			return Integer.toString(child.getId());		}		finally		{			lock.writeLock().unlock();		}	}	//---------------------------------------------------------------------------	public boolean remove(Dbms dbms, String path) throws SQLException	{		lock.writeLock().lock();		try		{			Setting s = resolve(path);			if (s == null)				return false;			remove(dbms, s);			return true;		}		finally		{			lock.writeLock().unlock();		}	}	//---------------------------------------------------------------------------	public boolean removeChildren(Dbms dbms, String path) throws SQLException	{		lock.writeLock().lock();		try		{			Setting s = resolve(path);			if (s == null)				return false;			for (Setting child : s.getChildren())				remove(dbms, child);			return true;		}		finally		{			lock.writeLock().unlock();		}	}	//---------------------------------------------------------------------------	//--- Auxiliary methods	//---------------------------------------------------------------------------	public boolean getValueAsBool(String path, boolean defValue)	{		String value = getValue(path);		return (value != null) ? value.equals("true") : defValue;	}	//---------------------------------------------------------------------------	//---	//--- Private methods	//---	//---------------------------------------------------------------------------	private void createSubTree(Setting s, List elemList)	{		for(Iterator i=elemList.iterator(); i.hasNext(); )		{			Element elem  = (Element) i.next();			String  sParId= elem.getChildText("parentid");			int     parId = sParId.equals("") ? -1 : Integer.parseInt(sParId);			if (s.getId() == parId)			{				String id     = elem.getChildText("id");				String name   = elem.getChildText("name");				String value  = elem.getChildText("value");				Setting child = new Setting(Integer.parseInt(id), name, value);				s.addChild(child);				i.remove();			}		}		for(Setting child : s.getChildren())			createSubTree(child, elemList);	}	//---------------------------------------------------------------------------	private String makeString(Object obj)	{		return (obj == null) ? null : obj.toString();	}	//---------------------------------------------------------------------------	private Setting resolve(String path)	{		StringTokenizer st = new StringTokenizer(path, SEPARATOR);		Setting s = root;		while(s != null && st.hasMoreTokens())		{			String child = st.nextToken();			if (child.startsWith("id:"))	s = find(s, Integer.parseInt(child.substring(3)));				else								s = s.getChild(child);		}		return s;	}	//---------------------------------------------------------------------------	private Setting find(Setting s, int id)	{		ArrayList<Setting> stack = new ArrayList<Setting>();		for (Setting child : s.getChildren())			stack.add(child);		while (!stack.isEmpty())		{			s = stack.get(0);			stack.remove(0);			if (s.getId() == id)				return s;			for (Setting child : s.getChildren())				stack.add(child);		}		return null;	}	//---------------------------------------------------------------------------	private Setting findAmongAdded(Dbms dbms, String path)	{		if (!path.startsWith("id:"))			return null;		if (path.indexOf(SEPARATOR) != -1)			return null;		int id = Integer.parseInt(path.substring(3));		for (Task task : tasks)		{			Setting s = task.getAddedSetting(dbms, id);			if (s != null)				return s;		}		return null;	}	//---------------------------------------------------------------------------	private Element build(Setting s, int level)	{		Element el = new Element(s.getName());		el.setAttribute("id", Integer.toString(s.getId()));		if (s.getValue() != null)		{			Element value = new Element("value");			value.setText(s.getValue());			el.addContent(value);		}		if (level != 0)		{			Element children = new Element("children");			for (Setting child : s.getChildren())				children.addContent(build(child, level -1));			if (children.getContentSize() != 0)				el.addContent(children);		}		return el;	}	//---------------------------------------------------------------------------	private void execute(Dbms dbms, String query, Object... args) throws SQLException	{		Vector v = new Vector();		for(Object obj : args)			v.add(obj);		dbms.execute(query, v);	}	//---------------------------------------------------------------------------	private int getNextSerial(Dbms dbms) throws SQLException	{		if (maxSerial == 0)		{			List   list = dbms.select("SELECT MAX(id) AS max FROM Settings").getChildren();			String max  = ((Element) list.get(0)).getChildText("max");			maxSerial = Integer.parseInt(max);		}		return ++maxSerial;	}	//---------------------------------------------------------------------------	private void remove(Dbms dbms, Setting s) throws SQLException	{		for (Setting child : s.getChildren())			remove(dbms, child);		execute(dbms, "DELETE FROM Settings WHERE id=?", s.getId());		tasks.add(Task.getRemovedTask(dbms, s));	}	//---------------------------------------------------------------------------	//---	//--- ResourceListener interface	//---	//---------------------------------------------------------------------------	private void flush(Object resource, boolean commit)	{		lock.writeLock().lock();		try		{			for(Iterator<Task> i=tasks.iterator(); i.hasNext();)			{				Task task = i.next();				if (task.matches(resource))				{					i.remove();					if (commit)						task.commit();				}			}		}		finally		{			lock.writeLock().unlock();		}	}	//---------------------------------------------------------------------------	//---	//--- Vars	//---	//---------------------------------------------------------------------------	private static final String SEPARATOR = "/";	private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();	private List<Task> tasks = new ArrayList<Task>();	private int maxSerial = 0;	//---------------------------------------------------------------------------	private ResourceListener resList = new ResourceListener()	{		public void close(Object resource) { flush(resource, true);  }		public void abort(Object resource) { flush(resource, false); }	};}//=============================================================================

⌨️ 快捷键说明

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