<commit_before>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
package ti.modules.titanium.xml;

import java.util.HashMap;

import org.appcelerator.titanium.TiContext;
import org.appcelerator.titanium.TiDict;
import org.appcelerator.titanium.TiProxy;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.Notation;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

public class NodeProxy extends TiProxy {

	private static HashMap<Node, NodeProxy> proxyCache = new HashMap<Node, NodeProxy>();
	
	private Node node;
	private TiDict constants;
	
	public NodeProxy(TiContext context, Node node)
	{
		super(context);
		this.node = node;
	}

	@Override
	public TiDict getConstants() {
		if (constants == null) {
			constants = new TiDict();
			constants.put("ATTRIBUTE_NODE", Node.ATTRIBUTE_NODE);
			constants.put("CDATA_SECTION_NODE", Node.CDATA_SECTION_NODE);
			constants.put("COMMENT_NODE", Node.COMMENT_NODE);
			constants.put("DOCUMENT_FRAGMENT_NODE", Node.DOCUMENT_FRAGMENT_NODE);
			constants.put("DOCUMENT_NODE", Node.DOCUMENT_NODE);
			constants.put("DOCUMENT_TYPE_NODE", Node.DOCUMENT_TYPE_NODE);
			constants.put("ELEMENT_NODE", Node.ELEMENT_NODE);
			constants.put("ENTITY_NODE", Node.ENTITY_NODE);
			constants.put("ENTITY_REFERENCE_NODE", Node.ENTITY_REFERENCE_NODE);
			constants.put("NOTATION_NODE", Node.NOTATION_NODE);
			constants.put("PROCESSING_INSTRUCTION_NODE", Node.PROCESSING_INSTRUCTION_NODE);
			constants.put("TEXT_NODE", Node.TEXT_NODE);
		}
		return constants;
	}
	
	public Node getNode() {
		return node;
	}
	
	// We cache node proxies so we're not constructing new ones on every single call
	// on node finalize we have to go back through and remove each proxy
	public static NodeProxy getNodeProxy(TiContext context, Node node) {
		NodeProxy proxy = proxyCache.get(node);
		if (proxy == null) {
			switch (node.getNodeType()) {
				case Node.ATTRIBUTE_NODE:
					proxy = new AttrProxy(context, (Attr)node);
					break;
				case Node.CDATA_SECTION_NODE:
					proxy = new CDATASectionProxy(context, (CDATASection)node);
					break;
				case Node.COMMENT_NODE:
					proxy = new CommentProxy(context, (Comment)node);
					break;
				case Node.DOCUMENT_FRAGMENT_NODE:
					proxy = new DocumentFragmentProxy(context, (DocumentFragment)node);
					break;
				case Node.DOCUMENT_NODE:
					proxy = new DocumentProxy(context, (Document)node);
					break;
				case Node.DOCUMENT_TYPE_NODE:
					proxy = new DocumentTypeProxy(context, (DocumentType)node);
					break;
				case Node.ELEMENT_NODE:
					proxy = new ElementProxy(context, (Element)node);
					break;
				case Node.ENTITY_NODE:
					proxy = new EntityProxy(context, (Entity)node);
					break;
				case Node.ENTITY_REFERENCE_NODE:
					proxy = new EntityReferenceProxy(context, (EntityReference)node);
					break;
				case Node.NOTATION_NODE:
					proxy = new NotationProxy(context, (Notation)node);
					break;
				case Node.PROCESSING_INSTRUCTION_NODE:
					proxy = new ProcessingInstructionProxy(context, (ProcessingInstruction)node);
					break;
				case Node.TEXT_NODE:
					proxy = new TextProxy(context, (Text)node);
					break;
				default:
					proxy = new NodeProxy(context, node);
					break;
			}
			proxyCache.put(node, proxy);
		}
		return proxy;
	}
	
	public static NodeProxy removeProxyForNode(TiContext context, Node node) {
		if (proxyCache.containsKey(node)) {
			return proxyCache.remove(node);
		}
		// if we're here then a proxy was never generated for this node
		// just return a temporary wrapper in this case
		return new NodeProxy(context, node);
	}
	
	@SuppressWarnings("unchecked")<commit_msg>Disable XML module's DOM NodeProxy caching; it leaks memory very badly. https://appcelerator.lighthouseapp.com/projects/32238-titanium-mobile/tickets/1579-memory-leak-xml-dom-nodeproxy-never-releases-proxy-objects-from-cache-on-android<commit_after>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
package ti.modules.titanium.xml;

import java.util.HashMap;

import org.appcelerator.titanium.TiContext;
import org.appcelerator.titanium.TiDict;
import org.appcelerator.titanium.TiProxy;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.Notation;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

public class NodeProxy extends TiProxy {

	private static HashMap<Node, NodeProxy> proxyCache = new HashMap<Node, NodeProxy>();
	
	private Node node;
	private TiDict constants;
	
	public NodeProxy(TiContext context, Node node)
	{
		super(context);
		this.node = node;
	}

	@Override
	public TiDict getConstants() {
		if (constants == null) {
			constants = new TiDict();
			constants.put("ATTRIBUTE_NODE", Node.ATTRIBUTE_NODE);
			constants.put("CDATA_SECTION_NODE", Node.CDATA_SECTION_NODE);
			constants.put("COMMENT_NODE", Node.COMMENT_NODE);
			constants.put("DOCUMENT_FRAGMENT_NODE", Node.DOCUMENT_FRAGMENT_NODE);
			constants.put("DOCUMENT_NODE", Node.DOCUMENT_NODE);
			constants.put("DOCUMENT_TYPE_NODE", Node.DOCUMENT_TYPE_NODE);
			constants.put("ELEMENT_NODE", Node.ELEMENT_NODE);
			constants.put("ENTITY_NODE", Node.ENTITY_NODE);
			constants.put("ENTITY_REFERENCE_NODE", Node.ENTITY_REFERENCE_NODE);
			constants.put("NOTATION_NODE", Node.NOTATION_NODE);
			constants.put("PROCESSING_INSTRUCTION_NODE", Node.PROCESSING_INSTRUCTION_NODE);
			constants.put("TEXT_NODE", Node.TEXT_NODE);
		}
		return constants;
	}
	
	public Node getNode() {
		return node;
	}
	
	// We cache node proxies so we're not constructing new ones on every single call
	// on node finalize we have to go back through and remove each proxy
	public static NodeProxy getNodeProxy(TiContext context, Node node) {
		//NodeProxy proxy = proxyCache.get(node);
		NodeProxy proxy;
		//if (proxy == null) {
			switch (node.getNodeType()) {
				case Node.ATTRIBUTE_NODE:
					proxy = new AttrProxy(context, (Attr)node);
					break;
				case Node.CDATA_SECTION_NODE:
					proxy = new CDATASectionProxy(context, (CDATASection)node);
					break;
				case Node.COMMENT_NODE:
					proxy = new CommentProxy(context, (Comment)node);
					break;
				case Node.DOCUMENT_FRAGMENT_NODE:
					proxy = new DocumentFragmentProxy(context, (DocumentFragment)node);
					break;
				case Node.DOCUMENT_NODE:
					proxy = new DocumentProxy(context, (Document)node);
					break;
				case Node.DOCUMENT_TYPE_NODE:
					proxy = new DocumentTypeProxy(context, (DocumentType)node);
					break;
				case Node.ELEMENT_NODE:
					proxy = new ElementProxy(context, (Element)node);
					break;
				case Node.ENTITY_NODE:
					proxy = new EntityProxy(context, (Entity)node);
					break;
				case Node.ENTITY_REFERENCE_NODE:
					proxy = new EntityReferenceProxy(context, (EntityReference)node);
					break;
				case Node.NOTATION_NODE:
					proxy = new NotationProxy(context, (Notation)node);
					break;
				case Node.PROCESSING_INSTRUCTION_NODE:
					proxy = new ProcessingInstructionProxy(context, (ProcessingInstruction)node);
					break;
				case Node.TEXT_NODE:
					proxy = new TextProxy(context, (Text)node);
					break;
				default:
					proxy = new NodeProxy(context, node);
					break;
			}
			//proxyCache.put(node, proxy);
		//}
		return proxy;
	}
	
	public static NodeProxy removeProxyForNode(TiContext context, Node node) {
		if (proxyCache.containsKey(node)) {
			return proxyCache.remove(node);
		}
		// if we're here then a proxy was never generated for this node
		// just return a temporary wrapper in this case
		return new NodeProxy(context, node);
	}
	
	@SuppressWarnings("unchecked")
{'fraction_non_alphanumeric': 0.10487776071808197, 'fraction_numerical': 0.006259596078894532, 'mean_word_length': 4.325786163522013, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 3}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5155733', 'n_tokens_mistral': 3166, 'n_tokens_neox': 2735, 'n_words': 632}