diff options
author | david_williams | 2006-04-10 15:46:03 +0000 |
---|---|---|
committer | david_williams | 2006-04-10 15:46:03 +0000 |
commit | 29e3aa8107f19d879ad72efd2954585896efd42c (patch) | |
tree | 82c11f76ead70a7073288c7214b9f6f3b05afdca /plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/CacheEventNode.java | |
parent | 322f3862efe7916fd36623e046cfa2598589146c (diff) | |
download | webtools.common-200604101723.tar.gz webtools.common-200604101723.tar.xz webtools.common-200604101723.zip |
This commit was manufactured by cvs2svn to create tag 'v200604101723'.v200604101723
Diffstat (limited to 'plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/CacheEventNode.java')
-rw-r--r-- | plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/CacheEventNode.java | 585 |
1 files changed, 0 insertions, 585 deletions
diff --git a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/CacheEventNode.java b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/CacheEventNode.java deleted file mode 100644 index e57583388..000000000 --- a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/CacheEventNode.java +++ /dev/null @@ -1,585 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2003, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.wst.common.internal.emf.resource; - - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.ecore.EObject; -import org.xml.sax.Attributes; - - -/** - * CacheEventNodes (CENOs) store information collected from SAX Events. This information can then be - * used once all necessary SAX Events have been generated to create and/or set values on EMF model - * objects. - * - * CacheEventNodes (CENOs) have a simple lifecycle: initialize, collect data, commit, discard. When - * initialized, CENOs will attempt to find the appropriate translator for a given XML element name, - * and also create/set any necessary EMF model values. Data is collected as SAX character() events - * are generated. On the SAX endElement event, the CENO is committed(), which is where it will - * complete its processing to create EMF model features. In those cases where it cannot complete its - * processing, it will defer its processing to the updateEMF() method of its parent. Defered - * processing is necessary to handle EMF features that require read ahead cues from the XML. CENOs - * will add themselves to their parents as children in a tree data structure. When an CENO - * determines it is the golden piece of information required to instantiate its parent feature, it - * will trigger its parent CENO to process the rest of the cached CENO tree. As mentioned, the - * building of a CENO tree will only occur for nodes with read ahead cues. - * - * discard() is invoked by init() to ensure that no junk state is left from a previous use of the - * CENO. commit() will call discard as needed. Because of the use of discard, CENOs can be pooled - * and reused. If a CENO determines that it is contained in a pool, it will manage its own release - * from that pool. Self- management is necessary because of the way in which CENOs might cache - * certain children while waiting to create the parent EMF feature. - * - * @author mdelder - */ -public class CacheEventNode { - - public static final String ROOT_NODE = "EMF_ROOT_NODE"; //$NON-NLS-1$ - - private String nodeName = null; - private Translator translator = null; - private Notifier emfOwner = null; - private StringBuffer buffer = null; - private List children = null; - private int versionID; - - /* - * The internal data structure used to store the attributes is a String[]. The choice was made - * to use an array to avoid the creation of another object (probably a Hashtable) and to exploit - * array-access times to get the name and value of the attributes (opposed to full fledged - * method invocations). - * - */ - private String[] attributes = null; - private CacheEventNode parent = null; - private CacheEventPool containingPool = null; - private Boolean ignorable = null; - - public CacheEventNode(CacheEventPool containingPool) { - this.containingPool = containingPool; - } - - /** - * Lifecycle method. init(TranslatorResource) will configure this Adapter as a ROOT node. - * - * This method will invoke discard() before completing its tasks. - */ - public void init(TranslatorResource resource) { - this.discard(); - this.setEmfOwner(resource); - this.setTranslator(resource.getRootTranslator()); - this.setVersionID(resource.getVersionID()); - this.nodeName = CacheEventNode.ROOT_NODE; - } - - /** - * Lifecycle method. init(CacheEventNode, String, Attributes) will configure this Adapter to be - * a non-ROOT node of the Adapter data structure - * - * This method will invoke discard() before completing its tasks. - */ - public void init(CacheEventNode parentArg, String nodeNameArg, Attributes attributesArg) { - this.discard(); - this.nodeName = nodeNameArg; - init(parentArg, attributesArg); - } - - private void init(CacheEventNode parentRecord, Attributes attributesArg) { - setParent(parentRecord); - - setAttributes(attributesArg); - if (parent != null) { - /* I am not the root */ - - /* - * If the parent is part of the DOM Path, then we ignore it and interact with the grand - * parent - */ - if (parent.translator != null && parent.isInDOMPath()) { - setParent(parent.getParent()); - } - - setVersionID(parent.getVersionID()); - if (parent.getEmfOwner() != null && parent.getTranslator() != null) { - - /* My parent had enough information to create themself */ - - if (parent.getParent() != null) { - setTranslator(parent.getTranslator().findChild(nodeName, parent.getEmfOwner(), getVersionID())); - - } else { - setTranslator(parent.getTranslator()); - } - - if (this.translator == null) { - /* Our translator is null! Ahh! Run! */ - throw new IllegalStateException("Parent Translator (" + parent.getTranslator() + //$NON-NLS-1$ - ") did not find a Child Translator for \"" + //$NON-NLS-1$ - nodeName + "\"."); //$NON-NLS-1$ - } - - if (this.translator.getReadAheadHelper(nodeName) == null && !this.translator.isManagedByParent()) { - /* - * I do not require a read ahead cue, and I am not managed by my parent so I can - * create an instance of my EMF object - */ - - Notifier myEmfOwner = this.translator.createEMFObject(getNodeName(), null); - setEmfOwner(myEmfOwner); - this.translator.setMOFValue(parent.getEmfOwner(), myEmfOwner); - } - /* - * Else I require a read ahead value or I am being managed by my parent, so I have - * no need to create an EMF object - */ - } - /* - * Else I am not mapped to the EMF stack (XML Elements found in the DOMPath are ignored) - */ - } - /* processAttributes is guarded and will not execute unless ready */ - processAttributes(); - - } - - /** - * commit() is invoked only if the CacheEventNode (CENO) has all the information they need and - * should be able to determine what to do to the EMF feature. - * - * The commit() method will invoke discard() when it has completed its tasks, if needed. Thus, - * after invoking this method, the CENO may have no meaningful state. If discard() is invoked, - * all previously held reference will be released in order to be made eligible for Garbage - * Collection. - * - */ - public void commit() { - - if (parent == null || this.isIgnorable()) { - discard(); - releaseFromContainingPool(); - return; - } - - ReadAheadHelper helper = null; - Translator activeTranslator = getTranslator(); - Translator parentTranslator = getParent().getTranslator(); - - if (parent != null && parent.getEmfOwner() == null) { - - /* - * Not enough information yet, add the CacheEventNode to the DOM Cache tree - */ - - parent.appendToBuffer(this); - if ((helper = getParent().getReadAheadHelper()) != null) { - /* - * If the parentRecord's emfOwner is null, then it must not be initialized therefore - * it or one of its ancestors must require read ahead clues - * - * The following if statement checks if the parent is the node waiting for a - * readAhead cue - */ - EObject parentOwner = null; - if (helper.nodeValueIsReadAheadName(getNodeName())) { - /* The readAheadName is the value of the qName child node */ - - /* We have enough information to create the EmfOwner in the parent! */ - parentOwner = parentTranslator.createEMFObject(getParent().getNodeName(), getBuffer()); - - /* - * Now we need to parse the cached DOM tree and update the emfOwner of the - * parent - */ - getParent().updateEMF(parentOwner); - - } else if (helper.nodeNameIsReadAheadName(getNodeName())) { - /* The readAheadName is the actual name of the child node (qName) */ - - /* We have enough information to create the EmfOwner in the parent! */ - parentOwner = parentTranslator.createEMFObject(getParent().getNodeName(), getNodeName()); - - /* - * Now we need to parse the cached DOM tree and update the emfOwner of the - * parent - */ - getParent().updateEMF(parentOwner); - } - - } /* Else an ancestor of the parent is waiting */ - - } else { - if (activeTranslator != null) { - if (activeTranslator.isManagedByParent()) { - - Object value = activeTranslator.convertStringToValue(getNodeName(), null, getBuffer(), getParent().getEmfOwner()); - activeTranslator.setMOFValue(getParent().getEmfOwner(), value); - processAttributes(); - } else { - - activeTranslator.setTextValueIfNecessary(getBuffer(), getEmfOwner(), getVersionID()); - } - - } - discard(); - releaseFromContainingPool(); - } - } - - /** - * Instruct the CacheEventNode to discard all references to make everything eligible for garbage - * collection. This should ONLY be called after commit has succeeded. In the case of EMF - * features that require a readAheadName, process not be completed in commit(), but rather will - * be defered to the updateEMF() method. This method was made private specifically because it - * could erase all information contained in the CacheEventNode before it has been processed. - * - */ - private void discard() { - translator = null; - emfOwner = null; - buffer = null; - if (children != null) - children.clear(); - children = null; - attributes = null; - parent = null; - } - - private void releaseFromContainingPool() { - if (containingPool != null) - containingPool.releaseNode(this); - } - - public boolean isIgnorable() { - if (ignorable == null) { - boolean result = false; - if (this.translator != null) { - if (this.translator.isEmptyContentSignificant()) { - result = false; - } else { - String domPath = this.translator.getDOMPath(); - result = (domPath != null) ? domPath.indexOf(this.nodeName) >= 0 : false; - } - } - ignorable = result ? Boolean.TRUE : Boolean.FALSE; - } - return ignorable.booleanValue(); - } - - /** - * Determines if a given child has a translator. - * - * @param childNodeName - * the name of the current XML child node - * @return true only if the childNodeName can be ignored (e.g. it is part of the DOM Path) - */ - public boolean isChildIgnorable(String childNodeName) { - boolean result = false; - - Translator childTranslator = null; - if (this.getTranslator() != null) { - childTranslator = this.getTranslator().findChild(childNodeName, this.getEmfOwner(), this.getVersionID()); - - if (childTranslator != null) { - if (childTranslator.isEmptyContentSignificant()) { - result = false; - } else { - String temp = null; - result = ((temp = childTranslator.getDOMPath()) != null) ? temp.indexOf(childNodeName) >= 0 : false; - } - } - } - - return result; - } - - public boolean isInDOMPath() { - boolean result = false; - - if (this.getTranslator() != null) { - - result = this.getNodeName().equals(this.getTranslator().getDOMPath()); - } - - return result; - } - - public String toString() { - StringBuffer output = new StringBuffer("CacheEventNode[");//$NON-NLS-1$ - output.append("nodeName=");//$NON-NLS-1$ - output.append(nodeName); - output.append("; translator=");//$NON-NLS-1$ - output.append(translator); - output.append("; emfOwner=");//$NON-NLS-1$ - try { - output.append(emfOwner); - } catch (RuntimeException re) { - output.append("Could not render as string!");//$NON-NLS-1$ - } - output.append("; buffer=");//$NON-NLS-1$ - output.append(this.buffer); - output.append("; hasChildren=");//$NON-NLS-1$ - output.append((children != null && children.size() > 0)); - if (children != null) { - for (int i = 0; i < this.children.size(); i++) { - output.append("\n\tchildren(");//$NON-NLS-1$ - output.append(i); - output.append("): ");//$NON-NLS-1$ - output.append(this.children.get(i)); - } - } - output.append("]");//$NON-NLS-1$ - return output.toString(); - } - - /** - * Updates the EMF model by creating EMF Features as necessary from the DOM Tree Cache - * - * @param owner - */ - public void updateEMF(EObject owner) { - this.setEmfOwner(owner); - if (this.parent != null) { - this.translator.setMOFValue((EObject) this.parent.getEmfOwner(), owner); - this.processAttributes(); - } - - this.updateEMF(); - } - - /** - * The translator and the owner of the parent CENO passed to this method should be nonnull - */ - public void updateEMF() { - if (this.children == null) - return; - - CacheEventNode child = null; - Translator childTranslator = null; - Object value = null; - if (this.getEmfOwner() != null) { - Notifier parentOwner = this.getEmfOwner(); - Translator parentTranslator = this.getTranslator(); - for (int i = 0; i < this.children.size(); i++) { - - child = (CacheEventNode) this.children.get(i); /* Create the EMF feature */ - if (this.isChildIgnorable(child.getNodeName())) { - this.addChildren(child.getChildren()); - } else { - childTranslator = parentTranslator.findChild(child.getNodeName(), parentOwner, child.getVersionID()); - child.setTranslator(childTranslator); - - value = childTranslator.convertStringToValue(child.getNodeName(), null, child.getBuffer(), parentOwner); - childTranslator.setMOFValue(parentOwner, value); - - if (childTranslator.isObjectMap()) { - child.setEmfOwner((Notifier) value); - childTranslator.setTextValueIfNecessary(child.getBuffer(), child.getEmfOwner(), getVersionID()); - } - - child.processAttributes(); - child.updateEMF(); /* update the EMF of the child */ - - } - child.discard(); - child.releaseFromContainingPool(); - } - this.children = null; - } - } - - public void addChild(CacheEventNode child) { - if (this.children == null) { - this.children = new ArrayList(); - } - if (parent != null && this.isIgnorable()) { - parent.addChild(child); - } else { - this.children.add(child); - } - } - - protected void addChildren(List childrenArg) { - if (this.children == null) { - this.children = new ArrayList(); - } - this.children.addAll(childrenArg); - } - - public boolean removeChild(CacheEventNode child) { - if (this.children == null) { - return false; - } - return this.children.remove(child); - } - - public List getChildren() { - return this.children; - } - - public ReadAheadHelper getReadAheadHelper() { - if (this.translator != null && this.translator.hasReadAheadNames()) { - return translator.getReadAheadHelper(nodeName); - } - return null; - } - - - /* See the documentation for the attributes field for info on how it is structured */ - public void setAttributes(Attributes attr) { - - /* - * The attributes returned from the parser may be stored by reference, so we must copy them - * over to a local data store - */ - if (attr != null && attr.getLength() > 0) { - - if (this.attributes == null) { - this.attributes = new String[attr.getLength() * 2]; - } - for (int i = 0; i < attr.getLength(); i++) { - this.attributes[i] = attr.getQName(i); - this.attributes[i + attr.getLength()] = attr.getValue(i); - } - - } - } - - /** - * processAttributes may be invoked multiple times. It is configured to only carry out the - * processing one time. After it successfully completes the construction of Translators and - * values it will discard the value of the attributes field by setting it to null. - * - */ - public void processAttributes() { - /* See the documentation for the attributes field for info on how it is structured */ - if (this.attributes != null && this.attributes.length > 0) { - - if (this.emfOwner != null && this.translator != null) { - Translator attrTranslator = null; - final int limit = this.attributes.length / 2; - Object value = null; - for (int i = 0; i < limit; i++) { - - /* Find the attribute translator by using the attribute name (attributes[i]) */ - attrTranslator = this.translator.findChild(this.attributes[i], this.emfOwner, this.versionID); - - if (attrTranslator != null) { - - /* - * Convert the value of corresponding attribute value (attributes[i+limit]) - * to a meaningful value - */ - value = attrTranslator.convertStringToValue(this.attributes[i + limit], (EObject) this.emfOwner); - attrTranslator.setMOFValue((EObject) this.emfOwner, value); - } - } - - /* Forget the attributes so we do not process them again */ - this.attributes = null; - } - } - } - - /** - * Appends data to the buffer stored by this CENO. Text will be extracted from the data array - * begining at positiong <i>start </i> and ending at position <i>start+length </i>. - * - * @param data - * @param start - * @param length - */ - public void appendToBuffer(char[] data, int start, int length) { - - if (parent != null && this.isIgnorable()) { - parent.appendToBuffer(data, start, length); - return; - } - - if (buffer == null) { - this.buffer = new StringBuffer(); - } - - /* - * acts as a more efficient form of "append". Using this method avoids the need to copy the - * data into its own data structure (e.g. String) before being added to the buffer - */ - this.buffer.insert(buffer.length(), data, start, length); - - } - - /** - * Add the given CENO as a child of this CENO. - * - * @param record - */ - public void appendToBuffer(CacheEventNode record) { - - this.addChild(record); - } - - public String getBuffer() { - if (this.buffer == null) { - return null; - } - return this.buffer.toString(); - } - - public Notifier getEmfOwner() { - return emfOwner; - } - - public CacheEventNode getParent() { - return parent; - } - - private void setParent(CacheEventNode record) { - this.parent = record; - } - - public Translator getTranslator() { - return this.translator; - } - - public void setEmfOwner(Notifier notifier) { - - this.emfOwner = notifier; - } - - public void setTranslator(Translator translator) { - this.translator = translator; - } - - public String getNodeName() { - return nodeName; - } - - public int getVersionID() { - - if (this.parent == null) { - try { - return ((TranslatorResource) this.getEmfOwner()).getVersionID(); - - } catch (RuntimeException re) { - } - } - return this.versionID; - } - - public void setVersionID(int i) { - versionID = i; - } - - -}
\ No newline at end of file |