bundles/org.apache.jasper.glassfish/src/org/apache/jasper/compiler/Parser.java
private boolean parseCustomTag(Node parent) throws JasperException {

	if (reader.peekChar() != '<') {
	    return false;
	}

        // Parse 'CustomAction' production (tag prefix and custom action name)
	reader.nextChar();	// skip '<'
	String tagName = reader.parseToken(false);
	int i = tagName.indexOf(':');
	if (i == -1) {
	    reader.reset(start);
	    return false;
	}

	String prefix = tagName.substring(0, i);
	String shortTagName = tagName.substring(i+1);

	// Check if this is a user-defined tag.
	String uri = pageInfo.getURI(prefix);
        if (uri == null) {
            // If error-on-undeclared-namespace is set to true in
            // jsp-property-group, then it is an error
            if (pageInfo.errorOnUndeclaredNamespace()) {
                 err.jspError(start, "jsp.error.undeclared.namespace", prefix);
            }

	    reader.reset(start);
            // Remember the prefix for later error checking
            pageInfo.putNonCustomTagPrefix(prefix, reader.mark());
	    return false;
	}

        TagLibraryInfo tagLibInfo = pageInfo.getTaglib(uri);
	TagInfo tagInfo = tagLibInfo.getTag(shortTagName);
	TagFileInfo tagFileInfo = tagLibInfo.getTagFile(shortTagName);
	if (tagInfo == null && tagFileInfo == null) {
	    err.jspError(start, "jsp.error.bad_tag", shortTagName, prefix);
	}
	Class tagHandlerClass = null;
	if (tagInfo != null) {
	    // Must be a classic tag, load it here.
	    // tag files will be loaded later, in TagFileProcessor
	    String handlerClassName = tagInfo.getTagClassName();
	    try {
	        tagHandlerClass = ctxt.getClassLoader().loadClass(handlerClassName);
	    } catch (Exception e) {
	        err.jspError(start, "jsp.error.loadclass.taghandler",
			     handlerClassName, tagName);
	    }
	}

        // Parse 'CustomActionBody' production:
        // At this point we are committed - if anything fails, we produce
        // a translation error.

        // Parse 'Attributes' production:
	Attributes attrs = parseAttributes();
	reader.skipSpaces();
	
        // Parse 'CustomActionEnd' production:
	if (reader.matches("/>")) {
	    if (tagInfo != null) {
		new Node.CustomTag(tagLibInfo.getRequiredVersion(),
                                   tagName, prefix, shortTagName, uri, attrs,
				   start, parent, tagInfo, tagHandlerClass);
	    } else {
		new Node.CustomTag(tagLibInfo.getRequiredVersion(),
                                   tagName, prefix, shortTagName, uri, attrs,
				   start, parent, tagFileInfo);
	    }
	    return true;
	}
	
        // Now we parse one of 'CustomActionTagDependent', 
        // 'CustomActionJSPContent', or 'CustomActionScriptlessContent'.
        // depending on body-content in TLD.

	// Looking for a body, it still can be empty; but if there is a
	// a tag body, its syntax would be dependent on the type of
	// body content declared in the TLD.
	String bc;
	if (tagInfo != null) {
	    bc = tagInfo.getBodyContent();
	} else {
	    bc = tagFileInfo.getTagInfo().getBodyContent();
	}

	Node tagNode = null;
	if (tagInfo != null) {
	    tagNode = new Node.CustomTag(tagLibInfo.getRequiredVersion(),
                                         tagName, prefix, shortTagName, uri,
					 attrs, start, parent, tagInfo,
					 tagHandlerClass);
	} else {
	    tagNode = new Node.CustomTag(tagLibInfo.getRequiredVersion(),
                                         tagName, prefix, shortTagName, uri,
					 attrs, start, parent, tagFileInfo);
	}

	parseOptionalBody( tagNode, tagName, bc );

	return true;
    }
private boolean parseCustomTag(Node parent) throws JasperException {

	if (reader.peekChar() != '<') {
	    return false;
	}

        // Parse 'CustomAction' production (tag prefix and custom action name)
	reader.nextChar();	// skip '<'
	String tagName = reader.parseToken(false);
	int i = tagName.indexOf(':');
	if (i == -1) {
	    reader.reset(start);
	    return false;
	}

	String prefix = tagName.substring(0, i);
	String shortTagName = tagName.substring(i+1);

	// Check if this is a user-defined tag.
	String uri = pageInfo.getURI(prefix);
        if (uri == null) {
            // If error-on-undeclared-namespace is set to true in
            // jsp-property-group, then it is an error
            if (pageInfo.errorOnUndeclaredNamespace()) {
                 err.jspError(start, "jsp.error.undeclared.namespace", prefix);
            }

	    reader.reset(start);
            // Remember the prefix for later error checking
            pageInfo.putNonCustomTagPrefix(prefix, reader.mark());
	    return false;
	}

        TagLibraryInfo tagLibInfo = pageInfo.getTaglib(uri);
	TagInfo tagInfo = tagLibInfo.getTag(shortTagName);
	TagFileInfo tagFileInfo = tagLibInfo.getTagFile(shortTagName);
	if (tagInfo == null && tagFileInfo == null) {
	    err.jspError(start, "jsp.error.bad_tag", shortTagName, prefix);
	}
	Class tagHandlerClass = null;
	if (tagInfo != null) {
	    // Must be a classic tag, load it here.
	    // tag files will be loaded later, in TagFileProcessor
	    String handlerClassName = tagInfo.getTagClassName();
	    try {
	        tagHandlerClass = ctxt.getClassLoader().loadClass(handlerClassName);
	    } catch (Exception e) {
	        err.jspError(start, "jsp.error.loadclass.taghandler",
			     handlerClassName, tagName);
	    }
	}

        // Parse 'CustomActionBody' production:
        // At this point we are committed - if anything fails, we produce
        // a translation error.

        // Parse 'Attributes' production:
	Attributes attrs = parseAttributes();
	reader.skipSpaces();
	
        // Parse 'CustomActionEnd' production:
	if (reader.matches("/>")) {
	    if (tagInfo != null) {
		new Node.CustomTag(tagLibInfo.getRequiredVersion(),
                                   tagName, prefix, shortTagName, uri, attrs,
				   start, parent, tagInfo, tagHandlerClass);
	    } else {
		new Node.CustomTag(tagLibInfo.getRequiredVersion(),
                                   tagName, prefix, shortTagName, uri, attrs,
				   start, parent, tagFileInfo);
	    }
	    return true;
	}
	
        // Now we parse one of 'CustomActionTagDependent', 
        // 'CustomActionJSPContent', or 'CustomActionScriptlessContent'.
        // depending on body-content in TLD.

	// Looking for a body, it still can be empty; but if there is a
	// a tag body, its syntax would be dependent on the type of
	// body content declared in the TLD.
	String bc;
	if (tagInfo != null) {
	    bc = tagInfo.getBodyContent();
	} else {
	    bc = tagFileInfo.getTagInfo().getBodyContent();
	}

	Node tagNode = null;
	if (tagInfo != null) {
	    tagNode = new Node.CustomTag(tagLibInfo.getRequiredVersion(),
                                         tagName, prefix, shortTagName, uri,
					 attrs, start, parent, tagInfo,
					 tagHandlerClass);
	} else {
	    tagNode = new Node.CustomTag(tagLibInfo.getRequiredVersion(),
                                         tagName, prefix, shortTagName, uri,
					 attrs, start, parent, tagFileInfo);
	}

	parseOptionalBody( tagNode, tagName, bc );

	return true;
    }
private boolean parseCustomTag ( Node parent ) throws JasperException { if ( reader . peekChar ( ) != ' ' ) { return false ; } // Parse 'CustomAction' production (tag prefix and custom action name) reader . nextChar ( ) ; // skip '<' String tagName = reader . parseToken ( false ) ; int i = tagName . indexOf ( ' ' ) ; if ( i == - 1 ) { reader . reset ( start ) ; return false ; } String prefix = tagName . substring ( 0 , i ) ; String shortTagName = tagName . substring ( i + 1 ) ; // Check if this is a user-defined tag. String uri = pageInfo . getURI ( prefix ) ; if ( uri == null ) { // If error-on-undeclared-namespace is set to true in // jsp-property-group, then it is an error if ( pageInfo . errorOnUndeclaredNamespace ( ) ) { err . jspError ( start , "jsp.error.undeclared.namespace" , prefix ) ; } reader . reset ( start ) ; // Remember the prefix for later error checking pageInfo . putNonCustomTagPrefix ( prefix , reader . mark ( ) ) ; return false ; } TagLibraryInfo tagLibInfo = pageInfo . getTaglib ( uri ) ; TagInfo tagInfo = tagLibInfo . getTag ( shortTagName ) ; TagFileInfo tagFileInfo = tagLibInfo . getTagFile ( shortTagName ) ; if ( tagInfo == null && tagFileInfo == null ) { err . jspError ( start , "jsp.error.bad_tag" , shortTagName , prefix ) ; } Class tagHandlerClass = null ; if ( tagInfo != null ) { // Must be a classic tag, load it here. // tag files will be loaded later, in TagFileProcessor String handlerClassName = tagInfo . getTagClassName ( ) ; try { tagHandlerClass = ctxt . getClassLoader ( ) . loadClass ( handlerClassName ) ; } catch ( Exception e ) { err . jspError ( start , "jsp.error.loadclass.taghandler" , handlerClassName , tagName ) ; } } // Parse 'CustomActionBody' production: // At this point we are committed - if anything fails, we produce // a translation error. // Parse 'Attributes' production: Attributes attrs = parseAttributes ( ) ; reader . skipSpaces ( ) ; // Parse 'CustomActionEnd' production: if ( reader . matches ( "/>" ) ) { if ( tagInfo != null ) { new Node . CustomTag ( tagLibInfo . getRequiredVersion ( ) , tagName , prefix , shortTagName , uri , attrs , start , parent , tagInfo , tagHandlerClass ) ; } else { new Node . CustomTag ( tagLibInfo . getRequiredVersion ( ) , tagName , prefix , shortTagName , uri , attrs , start , parent , tagFileInfo ) ; } return true ; } // Now we parse one of 'CustomActionTagDependent',  // 'CustomActionJSPContent', or 'CustomActionScriptlessContent'. // depending on body-content in TLD. // Looking for a body, it still can be empty; but if there is a // a tag body, its syntax would be dependent on the type of // body content declared in the TLD. String bc ; if ( tagInfo != null ) { bc = tagInfo . getBodyContent ( ) ; } else { bc = tagFileInfo . getTagInfo ( ) . getBodyContent ( ) ; } Node tagNode = null ; if ( tagInfo != null ) { tagNode = new Node . CustomTag ( tagLibInfo . getRequiredVersion ( ) , tagName , prefix , shortTagName , uri , attrs , start , parent , tagInfo , tagHandlerClass ) ; } else { tagNode = new Node . CustomTag ( tagLibInfo . getRequiredVersion ( ) , tagName , prefix , shortTagName , uri , attrs , start , parent , tagFileInfo ) ; } parseOptionalBody ( tagNode , tagName , bc ) ; return true ; }
/*
# '<' CustomAction CustomActionBody

CustomAction ::= TagPrefix ':' CustomActionName

TagPrefix ::= Name

CustomActionName ::= Name

CustomActionBody ::=   ( Attributes CustomActionEnd )
| <TRANSLATION_ERROR>

Attributes ::= ( S Attribute )* S?

CustomActionEnd ::=   CustomActionTagDependent
| CustomActionJSPContent
| CustomActionScriptlessContent

CustomActionTagDependent ::= TagDependentOptionalBody

CustomActionJSPContent ::= OptionalBody

CustomActionScriptlessContent ::= ScriptlessOptionalBody
/ * # < CustomAction CustomActionBody