// Util.dumpMatches(matches);
// System.out.println("=============> Finishing match dump");
CFDocument newDoc = new CFDocument();
matchStack = new Stack();
ArrayList rootElements = new ArrayList();
TagItem rootItem = new TagItem(0, 0, 0, "Doc Root");
int matchPos = 0;
StringBuffer nonParsedTextBuffer = new StringBuffer();
matchStack.push(rootItem);
ParseItemMatch lastMatch = null;
// little hackish way to detect cfscript based cfcs TODO: something better
if (inData.split("(?i).*component[^>]+\\{").length > 1) {
parseCFScript(inData);
newDoc.setDocumentRoot(rootItem);
return newDoc;
}
try {
for(; matchPos < matches.size(); matchPos++)
{
ParseItemMatch match = (ParseItemMatch)matches.get(matchPos);
String matchStr = match.match;
/*
if(lastMatch != null)
{
int difference = match.getStartPos() - lastMatch.getEndPos();
System.out.println(lastMatch.getMatch() + " -> " + match.getMatch() + ": diff of : "+ difference);
String nonParsedText = this.data2Parse.substring(lastMatch.getEndPos()+1, difference + lastMatch.getEndPos());
System.out.println("-> Thinks this is non matched: \'" + nonParsedText + "\'");
TextNode textNode = new TextNode(match.getLineNumber(), match.getStartPos(), match.getEndPos(), "#TEXT");
textNode.setNodeText(nonParsedText);
addDocItemToTree(match, matchStack, textNode);
}
*/
lastMatch = match;
if(matchStr.charAt(0) == '<') // Funnily enough this should always be the case!
{
if(matchStr.charAt(1) == '/') {
if(!handleClosingTag(match, matchStack)) {
parserState.addMessage(new ParseError(
getLineNumber(matchPos), matchPos, matchPos, "",
"Something in here is (probably) missing a closing tag or a closing \">\" and thus totally borking the parse!"
));
break;
}
} else {
// get just tag name, e.g. : <cffunction name="blah" becomes cffunction
String tagName = matchStr.split("[\\s/>]")[0];
tagName = "<"+tagName.substring(1, tagName.length()).toLowerCase();
int tagEnd = matchStr.indexOf(tagName)+tagName.length();
boolean isACloser = false;
//
// Find the end of the tag
int currPos = 0;
for(int quoteCount = 0; currPos < match.match.length(); currPos++) {
char currChar = match.match.charAt(currPos);
boolean inQuotes = (1 == quoteCount % 2);
if(!inQuotes && currChar == '>') {
break;
}
else if(currChar == '\"')
quoteCount++;
}
//
// Handle a self-closer (i.e. <cfproperty ... />
String attributes = "";
if(match.match.charAt(currPos-1) == '/') {
isACloser = true;
if(match.match.length() - tagEnd >= 2)
attributes = match.match.substring(tagEnd, match.match.length()-2); // minus one to strip the closing '/>'
}
else
attributes = match.match.substring(tagEnd, match.match.length()-1); // minus one to strip the closing '>'
switch(match.getMatchType())
{
case MATCHER_CFMLTAG:
if(tagName.startsWith("<cfif") || tagName.startsWith("<cfelseif") || tagName.startsWith("<cfmodule")
|| tagName.startsWith("<cfset"))
{
handleCFTag(tagName, match, matchStack, new ArrayList(), isACloser);
} else {
handleCFTag(tagName, match, matchStack, stripAttributes(attributes, match.lineNumber, tagEnd, match), isACloser);
}
if((tagName.startsWith("<cfif") || tagName.startsWith("<cfelseif") || tagName.startsWith("<cfmodule")
|| tagName.startsWith("<cfset"))
&& attributes.trim().length() == 0)
{
userMessage(0,
"stripAttributes", tagName + "> requires at least one attribute",
USRMSG_ERROR, match);
}
break;
case MATCHER_CFMLCOMMENT:
//System.out.println("CFParser::createDocTree() - Got a CFML comment!");
DocItem newComment = new CfmlComment(
match.getLineNumber(),
match.getStartPos(),
match.getEndPos(),
match.getMatch()
);
newComment.setItemData(match.getMatch());
addDocItemToTree(match, newComment);
break;
case MATCHER_CFSCRIPT:
tagName = tagName.substring(1, tagName.length());
TagItem newItem;
newItem = getNameBasedCfmlTag(tagName.substring(0, "cfscript".length()), match, getLineNumber(match.startPos));
newItem.initDictionary(DictionaryManager.getDictionary(DictionaryManager.CFDIC));
newItem.setItemData("");
addTagItemToTree(match, matchStack, isACloser, newItem);
handleCFScriptBlock(match, matchStack);
break;
default:
break;