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

📄 xmlpersistenceprovider.java

📁 eclipseme的最新版本的source,欢迎j2me程序员使用
💻 JAVA
字号:
/**
 * Copyright (c) 2003-2005 Craig Setera
 * All Rights Reserved.
 * Licensed under the Eclipse Public License - v 1.0
 * For more information see http://www.eclipse.org/legal/epl-v10.html
 */
package eclipseme.core.internal.persistence;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Stack;

import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import eclipseme.core.internal.EclipseMECorePlugin;
import eclipseme.core.internal.utils.XMLUtils;
import eclipseme.core.model.Version;
import eclipseme.core.persistence.IBundleReferencePersistable;
import eclipseme.core.persistence.IPersistable;
import eclipseme.core.persistence.IPersistenceProvider;
import eclipseme.core.persistence.PersistenceException;

/**
 * A persistence provider implementation that loads and stores
 * persistence information to/from an XML file.
 * <p />
 * Copyright (c) 2003-2005 Craig Setera<br>
 * All Rights Reserved.<br>
 * Licensed under the Eclipse Public License - v 1.0<p/>
 * <br>
 * $Revision: 1.3 $
 * <br>
 * $Date: 2006/05/28 20:06:37 $
 * <br>
 * @author Craig Setera
 */
public class XMLPersistenceProvider 
	implements IPersistenceProvider 
{
	private int identifier;
	private Element element;
	private Stack bundleStack;
	private Map referenceMap;
	private Map bundleMappings;
	
	/**
	 * Construct a new persistence provider instance
	 * that contains no persisted data.  Use the specified
	 * root element name for the resulting output.
	 * 
	 * @param rootElementName
	 * @throws PersistenceException 
	 */
	public XMLPersistenceProvider(String rootElementName) 
		throws PersistenceException 
	{
		this(createRootElement(rootElementName));
	}

	/**
	 * Construct a new persistence provider instance 
	 * given the persisted data in the specified document.
	 * 
	 * @param document
	 */
	public XMLPersistenceProvider(Document document) {
		this(document.getDocumentElement());
	}

	/**
	 * Construct a new persistence provider instance 
	 * given the persisted data in the specified root
	 * element.
	 * 
	 * * @param rootElement
	 */
	public XMLPersistenceProvider(Element rootElement) {
		element = rootElement;
		bundleStack = new Stack();
		referenceMap = new HashMap();
		
		// Set up a mapping from old bundle names to
		// the bundle that now can handle those instances
		bundleMappings = new HashMap();
		bundleMappings.put("eclipseme.toolkit.nokia", "eclipseme.toolkit.uei");
		bundleMappings.put("eclipseme.toolkit.sonyericsson", "eclipseme.toolkit.uei");
		bundleMappings.put("eclipseme.toolkit.sprint", "eclipseme.toolkit.uei");
		bundleMappings.put("eclipseme.toolkit.sun", "eclipseme.toolkit.uei");
	}

	/**
	 * Return the document to which the persistence is being output.
	 * @return
	 */
	public Document getDocument() {
		return element.getOwnerDocument();
	}
	
	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#loadBoolean(java.lang.String)
	 */
	public boolean loadBoolean(String name) 
		throws PersistenceException 
	{
		String value = loadString(name);
		return (value == null) ? false : "true".equalsIgnoreCase(value);
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#loadInteger(java.lang.String)
	 */
	public int loadInteger(String name) 
		throws PersistenceException 
	{
		String value = loadString(name);
		return (value == null) ? 0 : Integer.parseInt(value);
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#loadPersistable(java.lang.String)
	 */
	public IPersistable loadPersistable(String name) 
		throws PersistenceException 
	{
		IPersistable persistable = null;
		
		Element persistableElement = getNamedElement(name);
		if (persistableElement != null) {
			boolean pushedNewBundle = pushNewBundle(persistableElement);
			
			persistable = createPersistableInstance(persistableElement);
			if (persistable != null) {
				element = persistableElement;
				
				if (persistable instanceof IBundleReferencePersistable) {
					Bundle bundle = getCurrentBundle();
					if (bundle != null) {
						IBundleReferencePersistable bundlePersistable =
							(IBundleReferencePersistable) persistable;
						bundlePersistable.setBundle(bundle.getSymbolicName());
					}
				}
				
				persistable.loadUsing(this);

				// Make sure that the object can be picked up by reference
				String idString = persistableElement.getAttribute("id");
				Integer id = Integer.valueOf(idString);
				referenceMap.put(id, persistable);

				element = (Element) element.getParentNode();
			}
			
			if (pushedNewBundle) bundleStack.pop();
		}
		
		return persistable;
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#loadProperties(java.lang.String)
	 */
	public Properties loadProperties(String name) 
		throws PersistenceException 
	{
		Properties properties = null;

		Element namedElement = getNamedElement(name);
		if (namedElement != null) {
			properties = new Properties();
			
			NodeList propertyElements = namedElement.getElementsByTagName("property");
			for (int i = 0; i < propertyElements.getLength(); i++) {
				Element propertyElement = (Element) propertyElements.item(i);
				String key = propertyElement.getAttribute("key");
				String value = propertyElement.getAttribute("value");
				properties.setProperty(key, value);
			}
		}
		
		return properties;
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#loadReference(java.lang.String)
	 */
	public Object loadReference(String name) throws PersistenceException {
		Object object = null;
		
		Element namedElement = getNamedElement(name);
		if (namedElement != null) {
			try {
				String refidString = namedElement.getAttribute("refid");
				Integer refid = Integer.valueOf(refidString);
				object = referenceMap.get(refid);
			} catch (NumberFormatException e) {
				
			}
		}
		
		return object; 
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#loadString(java.lang.String)
	 */
	public String loadString(String name) 
		throws PersistenceException 
	{
		Element namedElement = getNamedElement(name);
		return (namedElement == null) ? null : namedElement.getAttribute("value");
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#storeBoolean(java.lang.String, boolean)
	 */
	public void storeBoolean(String name, boolean value) 
		throws PersistenceException 
	{
		storeString(name, Boolean.toString(value));
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#storeInteger(java.lang.String, int)
	 */
	public void storeInteger(String name, int value) 
		throws PersistenceException 
	{
		storeString(name, Integer.toString(value));
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#storePersistable(java.lang.String, eclipseme.core.persistence.IPersistable)
	 */
	public void storePersistable(String name, IPersistable value) 
		throws PersistenceException 
	{
		if (value != null) {
			element = XMLUtils.createChild(element, name);
			
			if (value instanceof IBundleReferencePersistable) {
				String bundle = ((IBundleReferencePersistable) value).getBundle();
				if (bundle != null) {
					element.setAttribute("bundle", bundle);
				}
			}
			element.setAttribute("class", value.getClass().getName());
			
			// Store material for making a reference
			Integer id = new Integer(identifier++);
			element.setAttribute("id", id.toString());
			referenceMap.put(value, id);
			
			value.storeUsing(this);
			element = (Element) element.getParentNode();
		}
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#storeProperties(java.lang.String, java.util.Properties)
	 */
	public void storeProperties(String name, Properties properties)
		throws PersistenceException 
	{
		if (properties != null) {
			Element propertiesElement = XMLUtils.createChild(element, name);
			
			Iterator entries = properties.entrySet().iterator();
			while (entries.hasNext()) {
				Element propertyElement = 
					XMLUtils.createChild(propertiesElement, "property");
	
				Map.Entry entry = (Map.Entry) entries.next();
				propertyElement.setAttribute("key", entry.getKey().toString());
				propertyElement.setAttribute("value", entry.getValue().toString());
			}
		}
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#storeReference(java.lang.String, java.lang.Object)
	 */
	public void storeReference(String name, Object referenceObject) 
		throws PersistenceException 
	{
		Integer refid = (Integer) referenceMap.get(referenceObject);
		if (refid != null) {
			Element newElement = XMLUtils.createChild(element, name);
			newElement.setAttribute("refid", refid.toString());
		}
	}

	/**
	 * @see eclipseme.core.persistence.IPersistenceProvider#storeString(java.lang.String, java.lang.String)
	 */
	public void storeString(String name, String value) 
		throws PersistenceException 
	{
		if (value != null) {
			Element newElement = XMLUtils.createChild(element, name);
			newElement.setAttribute("value", value);
		}
	}

	/**
	 * Return a new root element for use in persistence.  Use the
	 * specified element name for the root element.
	 * 
	 * @param elementName
	 * @return
	 * @throws PersistenceException 
	 */
	private static Element createRootElement(String elementName) 
		throws PersistenceException 
	{
		String pluginVersion = EclipseMECorePlugin.getPluginVersion();
		Version version = new Version(pluginVersion);
		
		Element element = null;
		try {
			element = XMLUtils.createRootElement(elementName, version);
		} catch (ParserConfigurationException e) {
			throw new PersistenceException(e.getMessage(), e);
		}
		
		return element;
	}

	/**
	 * Create a new persistable instance based on the information
	 * in the specified element.
	 * 
	 * @param persistableElement
	 * @return
	 * @throws PersistenceException
	 */
	private IPersistable createPersistableInstance(Element persistableElement) 
		throws PersistenceException 
	{
		IPersistable persistable = null;
		
		// Handle bundle references
		String className = persistableElement.getAttribute("class");
		try {
			Class clazz = loadClass(className);
			if (clazz != null) {
					persistable = (IPersistable) clazz.newInstance();
			}
		} catch (InstantiationException e) {
			throw new PersistenceException("InstantiationException: " + e.getMessage(), e);
		} catch (IllegalAccessException e) {
			throw new PersistenceException("IllegalAccessException: " + e.getMessage(), e);
		} catch (ClassNotFoundException e) {
			throw new PersistenceException("ClassNotFoundException: " + e.getMessage(), e);
		}
		
		return persistable;
	}

	/**
	 * Return the current bundle in effect for class loading
	 * purposes.
	 * 
	 * @return
	 */
	private Bundle getCurrentBundle() {
		Bundle bundle = null;
		
		if (!bundleStack.isEmpty()) {
			bundle = (Bundle) bundleStack.peek();
		}
		
		return bundle;
	}
	
	/**
	 * Return the named element within the current context or <code>null</code>
	 * if not found.
	 * 
	 * @param name
	 * @return
	 */
	private Element getNamedElement(String name) {
		Element namedElement = null;
		
		NodeList nodes = element.getElementsByTagName(name);
		
		// Find an element with the current element as the parent
		// node to avoid picking up nodes in objects held within
		// fields.
		for (int i = 0; (namedElement == null) && (i < nodes.getLength()); i++) {
			Element elem = (Element) nodes.item(i);
			if (elem.getParentNode().equals(element)) {
				namedElement = elem;
			}
		}
		
		return namedElement;
	}

	/**
	 * Load the specified class by finding the correct
	 * bundle.
	 * 
	 * @param bundleId
	 * @param className 
	 * @return
	 * @throws ClassNotFoundException 
	 */
	private Class loadClass(String className) 
		throws ClassNotFoundException 
	{
		Class clazz = null;
		
		Bundle bundle = getCurrentBundle();
		if (bundle != null) {
			clazz = bundle.loadClass(className);
		} else {
			clazz = getClass().getClassLoader().loadClass(className);
		}
		
		return clazz;
	}

	/**
	 * Push a new bundle reference on the stack if the persistable
	 * element references a bundle identifier.  Return a boolean
	 * indicating whether or not a bundle was actually pushed.
	 * 
	 * @param persistableElement
	 * @return
	 */
	private boolean pushNewBundle(Element persistableElement) {
		boolean pushed = false;
		
		String bundleId = persistableElement.getAttribute("bundle");
		if ((bundleId != null) && (bundleId.length() > 0)) {
			// Handle mapping one bundle reference to a different bundle.
			// This is done to handle changes in bundle references that
			// may occur between versions.
			String bundleMapping = (String) bundleMappings.get(bundleId);
			if (bundleMapping != null) {
				bundleId = bundleMapping;
			}
			
			// Lookup a new bundle as necessary
			Bundle bundle = Platform.getBundle(bundleId);
			if (bundle != null) {
				bundleStack.push(bundle);
				pushed = true;
			}
		}
		

		return pushed;
	}
}

⌨️ 快捷键说明

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