/*  Copyright (c) 2000, 2002 by Oracle Corporation. All Rights Reserved. */

package oracle.portal.provider.v1.http; 
import oracle.portal.provider.v1.PortletRenderRequest; 
import oracle.portal.provider.v1.PortletRendererUtil; 
import oracle.portal.provider.v1.ContentFilter; 
import oracle.portal.provider.v1.PortletException; 
import oracle.portal.provider.v1.PortletParameter; 
import oracle.portal.provider.v1.URLPortletParameter; 
import oracle.portal.provider.v1.RenderManager;
import oracle.portal.provider.v1.ManagedRenderer;
import java.io.IOException; 
import java.io.PrintWriter; 
import java.io.OutputStreamWriter; 
import java.net.URL;

/**
 * <p>BaseContentFilter is an absract class which contains
 * methods that are common across filters. </p>
 */
public abstract class BaseContentFilter implements ContentFilter 
{ 
    
    //Value of <urlContentType> Tag
    private String mUrlContentType = null; 
    
    //Value of <useAuthLinks> Tag
    private String mUseAuthLinks = null; 
    
    //Redirect Url tag value
    private String mRedirectUrlFieldName = null; 
    
    //<usePortalStyle> tag value
    private String mUsePortalStyle = null; 
    private String mRemoveClassProperty = null; 
    private String mInlineRendering = UrlServicesUtils.FALSE; 
    private String mBaseHRef = null; 
    private String mSecBaseHRef = null; 
    
    /**
     * Helper method which authenticates all hrefs with login  server url.
     * The provider renders the portlet according to the authorization embodied in
     * the cookie. All the links on the portlet that require authenticated access
     * must be wrapped with a call to the login server's external application login
     * processing routine.
     * The Parallel Page Engine sends along the information necessary to do
     * this wrapping, as provided by the Portal.
     * Basically, each link is of the format
     * http://loginserver.domain.com/pls/ls/ls.wwsso_app_admin.fapp_process_login?p_app_id=103&p_url_name=FlightDest&p_url_value="http://myserver.com/flights/flightAction=details"
     * Here,
     * 'p_app_id' is the application ID registered in the login server,
     * 'p_url_name' is the parameter name recognized by the External Application's
     *  Login URL as a URL that should be redirected to after a successful authentication.
     *  p_url_value' is the URL location that is requested.
     * Sample href
     * href="http://incq080f.idc.oracle.com:8088/pls/portal30_sso/portal30_sso.wwsso_app_admin.fapp_process_login?
     * p_url_value=http://152.69.169.62/servlets/flights/Flightaction/Ddetails/FlightId=123456
     * &p_url_name=FlightDest
     * &p_app_id=103
     * This works on the assumption that the url's that need to be wrapped by login server
     * need to be absolute urls and not relative urls
     * @param pr PortletRenderRequest
     * @param urlContent Url Content whose hrefs need to be authenticated.
     * @return String Authenticated Url Content
     */
    protected String authenticateFormLoginLinks(PortletRenderRequest pr, String urlContent, String redirectUrl, int debugLevel) 
    { 
        UrlServicesUtils.logMessage(pr.getProvider(), "render:authenticateFormLoginLinks: Before checking for Authtype",debugLevel); 
        String authenticatedContent = urlContent; 
        
        //Retrieve the URL for the Login Server
        String loginURL = pr.getLoginServerURL(); 
        PortletRendererUtil pruInstance = new PortletRendererUtil(); 
        if (redirectUrl != null) 
        { 
            
            //Wrap the redirect Url with the help of portlet render util instance
            String wrapperUrl = pruInstance.parameterizeLink(loginURL,"p_url_name=" + redirectUrl); 
            UrlServicesUtils.logMessage(pr.getProvider(),"render:authenticateFormLoginLinks:value of wrapper url first time= "+ 
            wrapperUrl,debugLevel); 
            
            //Wrap the redirect Url with the help of portlet render util instance
            String wrapperUrl2 = wrapperUrl + "&" + "p_url_value=" ; 
            UrlServicesUtils.logMessage(pr.getProvider(),"render:authenticateFormLoginLinks:value of wrapper url second time= " + wrapperUrl2,debugLevel); 
            
            //First Convert all the hrefs to LOgin server redirected href's
            // so href="http://my.yahoo.com" would be converted to
            // href="http://loginserverurl?p_url_name&p_url_value=http://my.yahoo.com"
            authenticatedContent = replaceAuthLinks(pr, 
            "<a","href", authenticatedContent, wrapperUrl2,false, debugLevel); 
            authenticatedContent = replaceAuthLinks(pr, 
            "<form","action", authenticatedContent, wrapperUrl2,false, debugLevel); 
            UrlServicesUtils.logMessage(pr.getProvider(),"render:authenticateFormLoginLinks:Replacement of href by wrapper url done", 
            debugLevel); 
        } // End of check for redirectUrl not being null
        else  
        { 
            UrlServicesUtils.logMessage(pr.getProvider(),"render:Value of redirect url is null",debugLevel); 
        } 
        return authenticatedContent; 
    } //end of authenticateFormLoginLinks
    
    protected String authenticateBasicLoginLinks(PortletRenderRequest pr, String urlContent, 
    String userInfo, int debugLevel) 
    { 
        
        //Modify basehref to include basic authentication
        //user information.
        //Example :
        //http://bug.us.oracle.com/secure/main.html
        //will be converted into a format
        //http://<user>:<password>@bug.us.oracle.com/secure/main.html
        String authenticatedContent = replaceAuthLinks(pr,"<a","href", urlContent, userInfo, true, debugLevel); 
        authenticatedContent = replaceAuthLinks(pr,"<form","action", authenticatedContent, userInfo, true, debugLevel); 
        return authenticatedContent; 
    } 
    
    /**
     * Method replaces HREF's to Login server HREF's, in the passed content.
     * @param pr ProviderRequest for this rendering.
     * @param tag contains tag ,that contains relative url
     * @param attribute contains the attribute containing relative url
     * @param InhtmlSource String containing the HtmlSource of pageURL
     * @param baseHref contains BaseHref tag
     * @return String contents with absolute url
     *
     */
    protected String replaceAuthLinks(PortletRenderRequest pr,String tag,String attribute, 
    String InhtmlSource,String baseHref, 
    boolean isBasicAuth, int debugLevel) 
    { 
        UrlServicesUtils.logMessage(pr.getProvider(),"Entering replaceAuthLinks"+ 
        " for tag = " + tag + " and attribute = " + attribute, 
        debugLevel, UrlServicesUtils.BASIC_LOGGING); 
        
        //Convert tag as well as attribute to lower case.
        tag = tag.toLowerCase(); 
        attribute = attribute.toLowerCase(); 
        StringBuffer htmlSource = null; 
        
        //Instantiate stringbuffer object with html contents passed.
        htmlSource = new StringBuffer(InhtmlSource); 
        
        //Lengths of html contents, basehref , tag to be replaced , attribute
        int htmlLength = htmlSource.length(); 
        int baseLength = baseHref.length(); 
        int tagLength = tag.length(); 
        int attributeLength = attribute.length(); 
        
        // Pointers used indicate start and end of tags and attributes, while
        //parsing
        int attribOffset,offset = 0; 
        int tagStart,tagEnd,attribStart,attribEnd; 
        int extractedTagLength; 
        
        // Extracted tag holder in uppercase.
        String extractedTag = ""; 
        String normalTag = ""; 
        
        //Contents Converted to uppercase. To overcome case-issues, while parsing.
        StringBuffer lowerHtmlSource = 
            new StringBuffer(htmlSource.toString().toLowerCase()); 
        do  
        { 
            
            // Content is parsed and the tag is extracted.
            attribOffset = 0; 
            tagStart = lowerHtmlSource.toString().indexOf(tag,offset); 
            if (tagStart ==- 1) 
            break; 
            offset = tagStart; 
            tagEnd = lowerHtmlSource.toString().indexOf('>' ,offset + tagLength); 
            if (tagEnd ==- 1) 
            break; 
            extractedTag = lowerHtmlSource.toString().substring(tagStart,tagEnd + 1); 
            normalTag = htmlSource.toString().substring(tagStart,tagEnd + 1); 
            extractedTagLength = extractedTag.length(); 
            
            // Location of attribute.
            attribStart = extractedTag.indexOf(attribute,attribOffset); 
            
            //If attribute exists, traverse till where its value begins.
            if (attribStart !=- 1) 
            { 
                attribOffset = attribStart + attributeLength; 
                while (extractedTag.charAt(attribOffset) == ' ' && attribOffset < extractedTagLength) 
                attribOffset++; 
                while (extractedTag.charAt(attribOffset) =='='&& attribOffset < extractedTagLength) 
                attribOffset++; 
                while (extractedTag.charAt(attribOffset) == ' ' && attribOffset < extractedTagLength) 
                attribOffset++; 
                while (extractedTag.charAt(attribOffset) == '\'' && attribOffset < extractedTagLength) 
                attribOffset++; 
                if (extractedTag.charAt(attribOffset) == '"') 
                attribOffset++; 
                offset = offset + attribOffset; 
                
                // Find the end of href
                int endOfAttribute = extractedTag.indexOf('"',attribOffset); 
                
                //check if attribute value ends with a '"'
                if (endOfAttribute ==- 1) 
                { 
                    endOfAttribute = extractedTag.indexOf(' ',attribOffset); 
                } 
                
                //If the attribute given is the last in this particualar tag ...
                if (endOfAttribute ==- 1) 
                { 
                    endOfAttribute = extractedTag.indexOf('>' ,attribOffset); 
                } 
                String attributeValue = 
                    normalTag.substring(attribOffset,endOfAttribute); 
                
                //If url referred by attribute starts with http then
                // base url is inserted.
                // It assumes that relative Url's have been converted to absolute before calling this function
                if (extractedTag.substring(attribOffset).startsWith("http") ) 
                { 
                    int iAttributeEnd = offset + attributeValue.length(); 
                    UrlServicesUtils.logMessage(pr.getProvider(),"replaceAuthLinks:offset :" + offset,debugLevel); 
                    UrlServicesUtils.logMessage(pr.getProvider(),"replaceAuthLinks:offset+endOfAttribute :" + iAttributeEnd,debugLevel); 
                    UrlServicesUtils.logMessage(pr.getProvider(),"Complete Extracted Tag length:" + extractedTag.length(),debugLevel); 
                    if (isBasicAuth) 
                    { 
                        StringBuffer basicAuthUserInfo = new StringBuffer(attributeValue); 
                        int index = basicAuthUserInfo.toString().indexOf("://"); 
                        index += 3; 
                        basicAuthUserInfo.insert(index,baseHref); 
                        htmlSource.replace(offset,iAttributeEnd,basicAuthUserInfo.toString() + '"'); 
                        lowerHtmlSource.replace(offset,iAttributeEnd,basicAuthUserInfo.toString() + '"'); 
                    } 
                    else  
                    { 
                        
                        //Now replace occurence of URL with input baseHref and encodedURL
                        htmlSource.replace(offset,iAttributeEnd,baseHref + attributeValue + '"'); 
                        lowerHtmlSource.replace(offset,iAttributeEnd,baseHref + attributeValue + '"'); 
                        UrlServicesUtils.logMessage(pr.getProvider(),"replaceAuthLinks: After UrlEncoding replacement",debugLevel); 
                    } 
                } 
                htmlLength = htmlSource.length(); 
            } 
            else  
            { 
                offset = offset + extractedTagLength; 
            } 
        } while (true);
        UrlServicesUtils.logMessage(pr.getProvider(),"replaceAuthLinks:Before returning"+ 
        htmlSource.toString(),debugLevel); 
        return htmlSource.toString(); 
    } //end of replaceAuthLinks
    
    /**
     * Specifies if the portlet style should be made compliant to portal style.
     * @param flag Check used to see if links have to be authorized.
     */
    public void setUsePortalStyle(String usePortalStyle) 
    { 
        mUsePortalStyle = usePortalStyle; 
    } // setUsePortalStyle()
    
    /**
     * Specifies if the links have to be authorized.
     * @param flag Check used to see if links have to be authorized.
     *
     */
    public void setUseAuthLinks(String flag) 
    { 
        mUseAuthLinks = flag; 
    } 
    
    /**
     * Returns the value of useAuthLinks.
     * @return String "true"/"false" depending on whether links are
     * authorized or not.
     *
     */
    protected String getUseAuthLinks() 
    { 
        return mUseAuthLinks; 
    } 
    
    /**
     * Get method for <redirectUrlFieldName> tag in provider.xml
     * @return redirectUrlFieldName value
     */
    protected String getRedirectUrlFieldName() 
    { 
        return mRedirectUrlFieldName; 
    } 
    
    /**
     * Set method for <redirectUrlFieldName> tag in provider.xml
     *
     * This will be used while making authenticated hyper links. Essentially
     * this is the field name understood by external application whose value
     * points to the Url location to be redirected to, after successful 
     * authentication.
     * @param redirectUrl Value of redirect url field.
     */
    public void setRedirectUrlFieldName(String redirectUrl) 
    { 
        mRedirectUrlFieldName = redirectUrl; 
    } 
    
    /**
     * sets the type of URL specified for a given rendering mode.
     * @param String of URL specified
     *
     */
    public void setUrlContentType(String type) 
    { 
        mUrlContentType = type; 
    } // setUrlContentType method
    
    /**
     * Returns the URL content type.
     * @return String URL Content Type (text/html or text/xml)
     */
    protected String getUrlContentType() 
    { 
        return mUrlContentType; 
    } // getUrlContentType method
    
    protected String getUsePortalStyle() 
    { 
        return mUsePortalStyle; 
    } 
    
    /**
     * Indicates URL Services to remove any styles used by this application.
     * Helpful in applying portal look and feel to the external application.
     * @param removeClassProperty Remove external applicaiton styles (true/false).
     */
    public void setRemoveClassProperty(String removeClassProperty) 
    { 
        mRemoveClassProperty = removeClassProperty; 
    } // setRemoveClassProperty()
    
    
    /** 
     * Creates an Html Form, whose action url points to the Parallel Servlet, 
     * and which encloses the portlet content. This in turn makes it possible
     * to redirect any events occuring in the portlet to the parallel page
     * engine.
     * @param pr PortletRenderRequest
     * @param htmlSource HTML content fetched from pageUrl.
     * @param debugLevel debug level parameter specified in zone.properties.
     */
    protected String addJavaScriptSubmitFunction(
        PortletRenderRequest pr, 
        String htmlSource, 
        int debugLevel) 
    { 
        StringBuffer urlContent = new StringBuffer(htmlSource.length()); 
        urlContent.append ("<FORM NAME=\"urlservices_parameter_form_"); 
        
        //Make sure this concept works out for situations where multiple instances
        //of the same portlet are present in a single page. In this situation we
        //cannot have same form names for all instances. Rather we hash portlet
        //reference name and add it to form's name.
        String hashedPortletRefName = UrlServicesUtils.hashString( 
        pr.getPortletReference().getName()); 
        urlContent.append(hashedPortletRefName); 
        urlContent.append("\" METHOD = \"GET\" "); 
        urlContent.append ("ACTION=\"" + 
        HttpPortletRendererUtil.htmlFormActionLink( 
        pr,PortletRendererUtil.PAGE_LINK) + "\""); 
        urlContent.append (">"); 
        urlContent.append ( 
        HttpPortletRendererUtil.htmlFormHiddenFields 
        (pr,PortletRendererUtil.PAGE_LINK)); 
        urlContent.append("<SCRIPT Language=\"JavaScript1.1\" > \n"); 
        urlContent.append(" function submitURL"); 
        urlContent.append(hashedPortletRefName + "(url)\n"); 
        urlContent.append(" {\n"); 
        urlContent.append(" document.urlservices_parameter_form_"); 
        urlContent.append(hashedPortletRefName + ".elements[\""); 
        urlContent.append(
            PortletRendererUtil.portletParameter(
                pr, 
                UrlServicesUtils.PAGE_URL));
        
            
        urlContent.append("\"].value=url;\n"); 
        urlContent.append(" document.urlservices_parameter_form_"); 
        urlContent.append(hashedPortletRefName); 
        urlContent.append(".submit();\n"); 
        urlContent.append(" }\n"); 
        urlContent.append("</SCRIPT>\n"); 
        String parameterPageUrl = 
            pr.getQualifiedParameter(UrlServicesUtils.PAGE_URL);
                
        if (parameterPageUrl == null) 
        {
            parameterPageUrl = ""; 
        }
        urlContent.append("<INPUT TYPE=\"hidden\" VALUE = \""); 
        urlContent.append(parameterPageUrl + "\" NAME = \""); 
        urlContent.append(
            PortletRendererUtil.portletParameter(
                pr, 
                UrlServicesUtils.PAGE_URL));
        urlContent.append("\" > \n"); 
        urlContent.append("</FORM>\n"); 
        urlContent.append(htmlSource); 
        return urlContent.toString(); 
    } //end of addJavaScriptSubmitFunction
    
    /**
     * Method adds javasript to HREF's in URLContent, to route the event through
     * Parallel Page Engine, instead of directly opening the link. Parallel Page
     * Engine will in turn redirects this event to appropriate renderer. URL 
     * pointed to by the link will be received by URLRenderer and this will 
     * become the new page url and the cycle continues.
     *
     * @param pr PortletRenderRequest
     * @param htmlSource HTML content fetched from pageUrl.
     * @param baseHref base href for making absolute links.
     * @param tag Name of the html tag
     * @param attribute name of attribute in the tag specified by {tag}
     * @param debugLevel debug level parameter specified in zone.properties.
     * 
     */
    protected String addJavaScriptToLink(
        PortletRenderRequest pr, 
        StringBuffer htmlSource, 
        String baseHref, 
        String tag, 
        String attribute, 
        int debugLevel) 
    { 
        
        // Pointers used indicate start and end of tags and attributes, while
        //parsing
        int attribOffset,offset = 0; 
        int tagStart, tagEnd, attribStart, attribEnd; 
        int tagLength = tag.length(); 
        int attributeLength = attribute.length(); 
        int htmlLength = htmlSource.length(); 
        int extractedTagLength; 
        String hashedPortletRefName = UrlServicesUtils.hashString( 
        pr.getPortletReference().getName()); 
        
        // Extracted tag holder in uppercase.
        String extractedTag = ""; 
        String normalTag = ""; 
        
        //Contents Converted to uppercase. To overcome case-issues, while parsing.
        StringBuffer lowerHtmlSource = 
            new StringBuffer(htmlSource.toString().toLowerCase()); 
        do  
        { 
            
            // Content is parsed and the tag is extracted.
            attribOffset = 0; 
            tagStart = lowerHtmlSource.toString().indexOf(tag,offset); 
            if (tagStart ==- 1) 
            {
                break; 
            }
            offset = tagStart; 
            tagEnd = lowerHtmlSource.toString().indexOf('>' ,offset + tagLength); 
            if (tagEnd ==- 1) 
            {
                break; 
            }
            extractedTag = 
                lowerHtmlSource.toString().substring(tagStart,tagEnd + 1); 
            normalTag = htmlSource.toString().substring(tagStart,tagEnd + 1); 
            extractedTagLength = extractedTag.length(); 
            
            // Location of attribute.
            attribStart = extractedTag.indexOf(attribute,attribOffset); 
            
            //If attribute exists, traverse till where its value begins.
            if (attribStart !=- 1) 
            { 
                attribOffset = attribStart + attributeLength; 
                while (extractedTag.charAt(attribOffset) == ' ' && attribOffset < extractedTagLength) 
                attribOffset++; 
                while (extractedTag.charAt(attribOffset) =='='&& attribOffset < extractedTagLength) 
                attribOffset++; 
                while (extractedTag.charAt(attribOffset) == ' ' && attribOffset < extractedTagLength) 
                attribOffset++; 
                while (extractedTag.charAt(attribOffset) == '\'' && attribOffset < extractedTagLength) 
                attribOffset++; 
                if (extractedTag.charAt(attribOffset) == '"') 
                attribOffset++; 
                offset = offset + attribOffset; 
                
                // Find the end of href
                int endOfAttribute = extractedTag.indexOf('"',attribOffset); 
                
                //check if attribute value ends with a '"'
                if (endOfAttribute ==- 1) 
                { 
                    endOfAttribute = extractedTag.indexOf(' ',attribOffset); 
                } 
                
                //If the attribute given is the last in this particualar tag ...
                if (endOfAttribute ==- 1) 
                { 
                    endOfAttribute = extractedTag.indexOf('>' ,attribOffset); 
                } 
                String attributeValue = normalTag.toString().substring( 
                attribOffset,endOfAttribute); 
                int iAttributeEnd = offset + attributeValue.length(); 
                StringBuffer temp = new StringBuffer(); 
                
                //Add javascript to this attribute value.
                temp.append("javascript:submitURL"); 
                temp.append(hashedPortletRefName); 
                temp.append("('"); 
                temp.append(attributeValue); 
                temp.append("')"); 
                htmlSource.replace(offset,iAttributeEnd,temp.toString()); 
                lowerHtmlSource.replace(offset,iAttributeEnd,temp.toString()); 
                htmlLength = htmlSource.length(); 
            } 
            else  
            { 
                offset = offset + extractedTagLength; 
            } 
        } while (true);
        return htmlSource.toString(); 
    } //end of addJavaScriptEvent
    
    /**
     * Sets the inline rendering of portlet links to true/false;
     * @param renderInline true/false
     */
    public void setInlineRendering(String renderInline) 
    { 
        mInlineRendering = renderInline; 
    } 
    
    /**
     * Returns if this portlet has inline rendering capabilities.
     * @return String true/false
     */
    public String getInlineRendering() 
    { 
        return mInlineRendering; 
    } 
    
    /**
     * Method which parses URLContent, removes any <base href=""> tag and
     * returns value of base href.
     *
     * @param urlContent URL Content to be searched for base href.
     * @return basehref from URL Content. If none found, returns null.
     */
    protected String popBaseHref(String urlContent) 
    { 
        String lowerContent = urlContent.toLowerCase(); 
        int begin = lowerContent.indexOf("<base"); 
        if (begin != -1) 
        {
            //Remove this tag and read base href.
            int end = lowerContent.indexOf(">", begin); 
            end++; 
            String tag = lowerContent.substring(begin, end); 
            
            //Travese till href attribute
            int attribStart = tag.indexOf("href"); 
            attribStart = tag.indexOf("=", attribStart); 
            attribStart++; 
            while ( tag.charAt(attribStart) == '"' || 
                    tag.charAt(attribStart) == ' ' ) 
            {
                attribStart++; 
            }
            int attribEnd = tag.indexOf('"', attribStart); 
            if (attribEnd ==- 1) 
            { 
                attribEnd = tag.indexOf(' ', attribStart); 
            } 
            if (attribEnd ==- 1) 
            { 
                attribEnd = tag.indexOf('>' , attribStart); 
            } 
            
            return tag.substring(attribStart, attribEnd);
        } 
        return null;
    } //popBaseHref
    
    /**
     * Method for setting base href.
     * @param baseHRef value of base href.
     */
    public void setBaseHRef(String baseHRef) 
    { 
        mBaseHRef = baseHRef; 
    } 
    
    /**
     * Get method for basehref tag.
     * @return Base Href.
     *
     */
    public String getBaseHRef() 
    { 
        return mBaseHRef; 
    } 
    /**
     * Get method for secondary basehref.
     * @return Secondary Base Href.
     *
     */
    public String getSecBaseHRef() 
    { 
        return mSecBaseHRef; 
    } 
    
    /**
     * Setter method specified in provider.xml, added for relative links not
     * preceeded by /.
     * If the domain is , <br>
     * http://aria.us.oracle.com:7777/ <br>
     * and the portlet is from page http://aria.us.oracle.com:7777/pls/oracle/ <br>
     * For tags that contain relative links without a / <br>
     * ex ., <code> "img src="test.gif""  </code><br>
     * the replaced relative url should be <br>
     * <pre> img src="http://aria.us.oracle.com:7777/pls/oracle/test.gif"  </pre>
     * but if baseHref is used in these cases , the replaced relative url will be, <br>
     * <pre> img src="http://aria.us.oracle.com:7777/test.gif" </pre> <br>
     * which will not work !
     */
    public void setSecBaseHRef(String secBaseHref) 
    { 
        
        //if secBaseHRef is not specified, baseHref is made secBaseHRef
        if (secBaseHref == null) 
        { 
            mSecBaseHRef = this.getBaseHRef(); 
        } 
        else  
        mSecBaseHRef = secBaseHref; 
    } 

    /**
     * Utility method which parses given URL and retrieves base href from it.
     * Any parameters appended to this URL will be removed and the base Url will
     * be returned.
     *
     * example :
     * Given URL :- http://myserver.com:myport/page?param1=value1&param2=value2
     * Base Href parsed :- http://myserver.com:myport/page.
     * @param pageUrl URL from which base href needs to be extracted
     */
    protected String parseBaseHref(String pageUrl) 
    { 
        String loc = pageUrl; 
        StringBuffer basehref = null; 
        try  
        { 
            URL url = new URL(loc); 
            basehref = new StringBuffer(url.getProtocol()); 
            basehref.append("://"); 
            basehref.append(url.getHost()); 
            if (url.getPort() !=- 1) 
            { 
                basehref.append(":"); 
                basehref.append(url.getPort()); 
            } 
            String file = url.getFile(); 
            int indexOfEndSlash = file.lastIndexOf("/"); 
            if (indexOfEndSlash ==- 1) 
            return pageUrl; 
            else  
            basehref.append(file.substring(0, indexOfEndSlash)); 
        } 
        catch (IOException e) 
        { 
            basehref = new StringBuffer(loc); 
        } 
        return basehref.toString(); 
    } //end of parseBaseHref

    /**
     * Method does the following things -
     * <ul><li> Searches the request to see if inline rendering parameter 
     *          is received.</li>
     * <li> Else reads pageUrl parameter from the respective managed renderer.</li>
     * <li> Extracts base href from the above url. </li></ul>
     */
    protected String getBaseHRef(PortletRenderRequest pr)
        throws PortletException
    {
        String inlinePageUrl = 
            pr.getQualifiedParameter(UrlServicesUtils.PAGE_URL);
        if(inlinePageUrl == null || inlinePageUrl.trim().length() == 0)
        {
            RenderManager rMan = 
                (RenderManager) pr.getPortlet().getRenderer();
            ManagedRenderer mRen = rMan.getManagedRenderer(pr);
            if(mRen instanceof URLRenderer)
            {
                inlinePageUrl = ((URLRenderer)mRen).getPageUrl();
            }
        }
        return parseBaseHref(inlinePageUrl);
    }

    protected void renderContents(PortletRenderRequest pr, 
        String urlContent, 
        int debugLevel, 
        int type) 
    throws PortletException 
    {
        //Call render's renderContents method
        RenderManager rMan = 
            (RenderManager) pr.getPortlet().getRenderer();
        ManagedRenderer mRen = rMan.getManagedRenderer(pr);
        if(mRen instanceof URLRenderer)
        {
            ((URLRenderer)mRen).renderContents(pr, urlContent, debugLevel, type);
        }
    }

} 