All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cfml.dictionary.DictionaryContentHandler Maven / Gradle / Ivy

/*
 * Created on Feb 27, 2004
 *
 * The MIT License
 * Copyright (c) 2004 Rob Rohan
 *
 * Permission is hereby granted, free of charge, to any person obtaining a 
 * copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the Software 
 * is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 * SOFTWARE.
 */
package cfml.dictionary;

import java.util.Map;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

/**
 * @author Rob
 *
 *         Handles the Sax events against a dictionary. This was ripped from Treebeard with permission
 */
public class DictionaryContentHandler implements ContentHandler {
	// keep track of the location
	// private Locator locator;
	// private Map namespaceMappings;
	
	private Map dtags;
	private Map dfunctions;
	private Map dscopeVars;
	private Map dscopes;
	
	/** used to mark which part of the xml doc we are in */
	private String currenttag = "";
	/** current tag/function being built */
	private Procedure currentitem = null;
	private Parameter paramItem = null;
	private Function methoditem = null;
	
	public DictionaryContentHandler(Map tags, Map functions, Map scopeVars, Map scopes) {
		dtags = tags;
		dfunctions = functions;
		dscopeVars = scopeVars;
		dscopes = scopes;
		// namespaceMappings = new java.util.HashMap();
	}
	
	/**
	 * sets the documnet locator
	 * 
	 * @param locator
	 *            the document locator
	 */
	public void setDocumentLocator(Locator locator) {
		// this.locator = locator;
	}
	
	/**
	 * guesses if the passed string is "true" or "false"
	 * 
	 * @param bstring
	 *            the "true" "false" string
	 * @return the string in a boolean form
	 */
	private boolean parseBoolean(String bstring) {
		if (bstring.equalsIgnoreCase("true") || bstring.equalsIgnoreCase("yes")) {
			return true;
		}
		
		return false;
	}
	
	private boolean inTriggerBlock = false;
	
	/**
	 * Handles the start of a triggers tag. At present it just records the fact that we are in a triggers block so that
	 * any trigger set exists only in triggers blocks.
	 * 
	 * @param attribs
	 *            XML tag attributes
	 */
	private void handleTriggersStart(Attributes attribs) {
		if (this.paramItem == null) {
			System.err.println("Got a  block outside of a parameter!");
		} else
			this.inTriggerBlock = true;
	}
	
	/**
	 * Handles a closing triggers tag.
	 * 
	 * Simply records the fact that the triggers block has ended.
	 *
	 */
	private void handleTriggersEnd() {
		this.inTriggerBlock = false;
	}
	
	/**
	 * Handles a selectedValue tag. Adds the trigger details to the currently open parameter (if no parameter open or
	 * the selectedValue tag is not in a parameter then an error will be reported)
	 * 
	 * @param attributes
	 *            Attributes for the xml
	 */
	private void handleSelectedValue(org.xml.sax.Attributes attributes) {
		if (!this.inTriggerBlock) {
			System.err.println("Got a  outside of a valid triggers block!");
			return;
		}
		
		String attrName = attributes.getValue("attributeName");
		String value = attributes.getValue("value");
		boolean required = attributes.getValue("required").compareToIgnoreCase("true") == 0;
		String indexVal = attributes.getValue("index");
		int index = -1;
		if (indexVal != null) {
			index = Integer.parseInt(indexVal);
		}
		this.paramItem.addTrigger(Trigger.CreateSimpleTrigger(attrName, value, required, index));
		
		// System.out.println("DictionaryContentHandler::handleSelectedVaule - Attr: \'" + this.paramItem.getName() +
		// "\' + Added trigger for \'" + attrName + "\'=\'" + value + "\'");
	}
	
	/** process a start element */
	public void startElement(String namespace, String localName, String str2, org.xml.sax.Attributes attributes)
			throws SAXException {
		// save the current tag so we can see where we were
		this.currenttag = str2.toLowerCase();
		
		if (str2.equals("tag")) {
			handleTagStart(attributes);
		} else if (str2.equals("function")) {
			handleFunctionStart(attributes);
		} else if (str2.equals("parameter")) {
			handleParameterStart(attributes);
		} else if (str2.equals("value")) {
			handleValueStart(attributes);
		} else if (str2.equals("help")) {
			// adds help
		} else if (str2.equals("component")) {
			handleComponentStart(attributes);
			// these came with the dict from CFB side, looks like a work in progress
			// } else if(str2.equals("scopevar")) {
			// handleScopeStart(attributes);
		} else if (str2.equals("scope")) {
			handleScopeStart(attributes);
		} else if (str2.equals("triggers")) {
			handleTriggersStart(attributes);
		} else if (str2.equals("selectedValue")) {
			handleSelectedValue(attributes);
		}
		
	}
	
	private void handleTagStart(org.xml.sax.Attributes attributes) {
		// all the attribtues we are going to need to make a tag
		byte creator = 0;
		String name = "";
		boolean single = false;
		boolean xmlstyle = false;
		boolean hybrid = false;
		boolean anyAttribute = false;
		boolean endtagrequired = false;
		
		// get all the attributes needed for the tag
		for (int x = 0; x < attributes.getLength(); x++) {
			String attrname = attributes.getQName(x).toLowerCase();
			if (attrname.equals("creator")) {
				creator = Byte.parseByte(attributes.getValue(x));
			} else if (attrname.equals("name")) {
				name = attributes.getValue(x);
			} else if (attrname.equals("single")) {
				single = parseBoolean(attributes.getValue(x));
			} else if (attrname.equals("xmlstyle")) {
				xmlstyle = parseBoolean(attributes.getValue(x));
			} else if (attrname.equals("hybrid")) {
				hybrid = parseBoolean(attributes.getValue(x));
			} else if (attrname.equals("allowanyattribute")) {
				anyAttribute = parseBoolean(attributes.getValue(x));
			} else if (attrname.equals("endtagrequired")) {
				endtagrequired = parseBoolean(attributes.getValue(x));
			}
		}
		
		// System.out.println("Tag: " + creator + " " + name + " " + single + " " + xmlstyle);
		// create a new tag
		this.currentitem = new Tag(name, single, xmlstyle, creator, hybrid, anyAttribute, endtagrequired);
	}
	
	private void handleFunctionStart(org.xml.sax.Attributes attributes) {
		// create a new function
		byte creator = 0;
		String name = "";
		String returns = "";
		
		// get all the attributes needed for the tag
		for (int x = 0; x < attributes.getLength(); x++) {
			String attrname = attributes.getQName(x).toLowerCase();
			if (attrname.equals("creator")) {
				creator = Byte.parseByte(attributes.getValue(x));
			} else if (attrname.equals("name")) {
				name = attributes.getValue(x);
			} else if (attrname.equals("returns")) {
				returns = attributes.getValue(x);
			}
		}
		// System.out.println("Fun: " + creator + " " + name + " " + returns);
		// create a new function
		if (this.currentitem instanceof Component) {
			this.methoditem = new Function(name, returns, creator);
		} else {
			this.currentitem = new Function(name, returns, creator);
		}
	}
	
	/**
	 * Handles a new parameter. Not added until the closing tag is found.
	 * 
	 * @param attributes
	 *            The attributes associated with the parameter
	 */
	private void handleParameterStart(org.xml.sax.Attributes attributes) {
		// get the name and type
		String name = "";
		String type = "";
		boolean required = false;
		String defaultValue = null;
		String category = "General";
		
		for (int x = 0; x < attributes.getLength(); x++) {
			String attrname = attributes.getQName(x).toLowerCase();
			if (attrname.equals("type")) {
				type = attributes.getValue(x);
			} else if (attrname.equals("name")) {
				name = attributes.getValue(x);
			} else if (attrname.equals("required")) {
				required = parseBoolean(attributes.getValue(x));
			} else if (attrname.equals("default")) {
				defaultValue = attributes.getValue(x);
			} else if (attrname.equals("category")) {
				category = attributes.getValue(x);
			}
		}
		
		// System.out.println("Param: " + name + " " + type + " " + required);
		//
		// Create a new parameter and store it as the current parameter
		this.paramItem = new Parameter(name, type, required, defaultValue, category);
	}
	
	/**
	 * Handles a closing parameter tag. Performs whatever finishing up is required and stores the parameter for it's
	 * associated method/tag.
	 */
	private void handleParameterEnd() {
		//
		// Attach the finished parameter to the current item
		if ((currentitem instanceof Function || currentitem instanceof Tag) && paramItem != null) {
			currentitem.addParameter(paramItem);
		} // TODO: Isn't the below in the wrong place, should it be a child of the above if?
		else if (methoditem != null && paramItem != null) {
			methoditem.addParameter(paramItem);
		}
		
		//
		// Reset the paramitem
		paramItem = null;
	}
	
	/**
	 * Handles the open tag for a value.
	 * 
	 * 
	 * @param attributes
	 *            The attributes for the tag.
	 */
	private void handleValueStart(org.xml.sax.Attributes attributes) {
		//
		// Create a new value and assign it to the current parameter
		String option = attributes.getValue(0);
		
		if (option != null && paramItem != null)
			paramItem.addValue(new Value(option));
	}
	
	private void handleValueEnd() {
		
	}
	
	private void handleComponentStart(org.xml.sax.Attributes attributes) {
		// all the attribtues we are going to need to make a tag
		byte creator = 0;
		String path = "";
		String name = "";
		String framework = "";
		;
		
		// get all the attributes needed for the tag
		for (int x = 0; x < attributes.getLength(); x++) {
			String attrname = attributes.getQName(x).toLowerCase();
			if (attrname.equals("creator")) {
				creator = Byte.parseByte(attributes.getValue(x));
			} else if (attrname.equals("path")) {
				path = attributes.getValue(x);
				String[] tmp = path.split("\\.");
				name = tmp[tmp.length - 1];
			} else if (attrname.equals("framework")) {
				framework = attributes.getValue(x);
			}
		}
		
		// System.out.println("Tag: " + creator + " " + name + " " + single + " " + xmlstyle);
		// create a new tag
		this.currentitem = new Component(name, path, framework, creator);
	}
	
	private void handleScopeStart(org.xml.sax.Attributes attributes) {
		// create a new value and assign it to the current parameter
		String type = attributes.getValue(0);
		String scopeVar = attributes.getValue(1);
		if (scopeVar.indexOf(".") > 0) {
			String scope = scopeVar.substring(0, scopeVar.indexOf("."));
			dscopes.put(scope, new ScopeVar(type, scope));
		}
		// System.out.println("Value: " + scope);
		if (currentitem instanceof Component) {
			((Component) currentitem).addScope(scopeVar);
			dscopeVars.put(scopeVar, currentitem);
		} else {
			dscopeVars.put(scopeVar, new ScopeVar(type, scopeVar));
		}
	}
	
	/** process an end element */
	public void endElement(String str, String str1, String str2) throws SAXException {
		str2 = str2.toLowerCase();
		if (str2.equals("tag")) {
			// add the current item to the tag map
			if (this.currentitem != null)
				dtags.put(currentitem.getName(), (Tag) currentitem);
			// System.err.println(this.currentitem);
		} else if (str2.equals("function")) {
			// add the current item to the function map
			if (this.currentitem instanceof Component) {
				((Component) currentitem).addMethod(methoditem);
				methoditem = null;
			} else if (this.currentitem instanceof Function) {
				dfunctions.put(currentitem.getName(), (Function) currentitem);
			}
		} else if (str2.equals("parameter")) {
			handleParameterEnd();
		} else if (str2.equals("value")) {
			handleValueEnd();
		} else if (str2.equals("help")) {
			// nothing?
		} else if (str2.equals("component")) {
			if (this.currentitem instanceof Component) {
				this.currentitem = null;
			}
			
		} else if (str2.equals("scope")) {
			// Do nothing.
		} else if (str2.equals("triggers")) {
			handleTriggersEnd();
		}
		currenttag = "";
	}
	
	/** process the start prefix */
	public void startPrefixMapping(String str, String str1) throws SAXException {
		// save the mappings for later use
		// namespaceMappings.put(str1,str);
	}
	
	/** process the end prefix */
	public void endPrefixMapping(String str) throws SAXException {
		;
	}
	
	/** process characters */
	public void characters(char[] values, int start, int length) throws SAXException {
		
		if (currenttag.equalsIgnoreCase("help")) {
			StringBuffer resvalue = new StringBuffer();
			
			for (int x = start; x < (start + length); x++) {
				resvalue.append(values[x]);
			}
			
			// if the current item is not null and the prams are its help for the
			// current item
			if (currentitem != null && paramItem == null) {
				// for some reason M8 calls this a bunch of times, but only with
				// the cfml dictionary. So this is kind of a hack to get it to
				// load the help right... this slows it down a bit
				// TODO figure out whats up
				if (resvalue.toString().trim().length() > 0) {
					currentitem.setHelp(
							currentitem.getHelp() + " " + resvalue.toString().trim().replace('\t', ' ') + "\n");
				}
			}
			// if the param is not null its help for the param
			else if (currentitem != null && paramItem != null) {
				// TODO here too
				// paramitem.setHelp(resvalue.toString().trim().replace('\t',' '));
				if (resvalue.toString().trim().length() > 0) {
					paramItem.setHelp(paramItem.getHelp() + " " + resvalue.toString().trim().replace('\t', ' ') + "\n");
				}
			}
		}
	}
	
	/** process the end of the document */
	public void endDocument() throws SAXException {
		;
	}
	
	public void ignorableWhitespace(char[] values, int param, int param2) throws SAXException {
		;
	}
	
	/** process the processing instructions */
	public void processingInstruction(String str, String str1) throws SAXException {
		;
	}
	
	public void skippedEntity(String str) throws SAXException {
		;
	}
	
	/** process the start of the documnet */
	public void startDocument() throws SAXException {
		;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy