Package org.jasig.portal.utils

Source Code of org.jasig.portal.utils.AbsoluteURLFilter

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.jasig.portal.utils;

import org.jasig.portal.PortalException;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.helpers.AttributesImpl;

/**
* <p>Replaces all relative URLs with absolute URLs.</p>
* @author Ken Weiner, kweiner@unicon.net
* @version $Revision: 19776 $
*/
public abstract class AbsoluteURLFilter extends SAX2FilterImpl {
 
  protected String baseUrl = null;
 
  /**
   * A constructor which receives a ContentHandler to which
   * filtered SAX events are passed
   * @param handler the ContentHandler to which filtered SAX events are passed
   */
  protected AbsoluteURLFilter(ContentHandler handler) {
    super(handler);
  }
 
  /**
   * A factory method that uses a mime type to decide which kind of
   * AbsoluteURLFilter to instantiate.  There are currently two types
   * of markup supported: XHTML and WML.
   * @param mimeType the mime type of the markup that this filter will apply to
   * @param baseUrl the base URL to be prepended to relative URL paths
   * @param handler the ContentHandler to which to pass along filtered SAX events
   * @return filter the AbsoluteURLFilter matching the mimeType
   */ 
  public static final AbsoluteURLFilter newAbsoluteURLFilter(String mimeType, String baseUrl, ContentHandler handler) throws PortalException {
    AbsoluteURLFilter filter = null;
   
    if (mimeType != null) {
      if (mimeType.equals("text/html")) {
        filter = new XHTMLURLFilter(handler);
      } else if (mimeType.equals("text/vnd.wap.wml")) {
        filter = new WMLURLFilter(handler);
      } else {
        throw new PortalException("AbsoluteURLFilter.newAbsoluteURLFilter(): Unable to locate AbsoluteURLFilter for mime type '" + mimeType + "'");
      }
    } else {
      throw new PortalException("AbsoluteURLFilter.newAbsoluteURLFilter(): Unable to create AbsoluteURLFilter. Mime type is null.");
    }

    filter.baseUrl = baseUrl;
   
    return filter;
  }

  /**
   * Sets the base URL.
   * @param url the new base URL
   */
  protected void setBaseUrl(String url)
  {
    if (url != null)
      this.baseUrl = url;
  }

  /**
   * A helper method for derivitive classes to easily fix an attribute
   * that has a relative URL value
   * @param elementName the element name containing an attribute of name attName
   * @param attName the name of the attribute of elementName
   * @param qName the name of the current element
   * @param atts the attibutes of the current element
   * @param attsImpl the attributes implementation to contain the new attribute value
   */
  protected final void fixURL(String elementName, String attName, String qName, Attributes atts, AttributesImpl attsImpl)
  {
    if (qName.equalsIgnoreCase(elementName))
    {
      String attValue = atts.getValue(attName);
      if (attValue != null)
      {
        // Assume that if the attribute value exists and doesn't contain a
        // colon, or if the URL contains a colon and there's a
        // slash before the first colon, then it is a relative URL
        // (http://<something> and mailto:<something> are both valid,
        // absolute URLs)
        int i = attValue.indexOf(":");
        if ( i==-1 || (i!=-1 && attValue.substring(0, i).indexOf("/")!=-1) )
        {
          i = baseUrl.indexOf("://");
          int i2 = baseUrl.indexOf("/", i+3);
          if (attValue.startsWith("/"))
          {
            // Prepend the scheme and the host to the attribute value (HTTP)
            if (i != -1)
            {
              if (i2 != -1)
                attValue = baseUrl.substring(0, i2).concat(attValue);
              else
                attValue = baseUrl.concat(attValue);
            }
          }
          else if (attValue.trim().equals(""))
            attValue = baseUrl;
          else if (attValue.trim().startsWith("?") || attValue.trim().startsWith("#"))
            attValue = baseUrl.concat(attValue);
          else
          {
            if (i2 != -1)
            {
              if (baseUrl.indexOf("?") != -1)
                attValue = baseUrl.substring(0, baseUrl.substring(0, baseUrl.indexOf( "?" )).lastIndexOf("/")+1).concat(attValue);
              else
                attValue = baseUrl.substring(0, baseUrl.lastIndexOf("/")+1).concat(attValue);
            }
            else
              attValue = baseUrl.concat("/").concat(attValue);
          }

          if (attValue.indexOf("/../") != -1)
            attValue = removeUpDirs(attValue);
        }       

        int index = atts.getIndex(attName);
        attsImpl.setAttribute(index, atts.getURI(index), atts.getLocalName(index), attName, atts.getType(index), attValue);
      }
    }
  }

  /**
   * Removes the '/../' in the URL.  Some browsers and web
   * servers do not handle these URLs correctly.
   * @param url the absolute URL generated from the fixURL method
   */
  private String removeUpDirs(String url)
  {
    String begin;
    String end;
    int upDirIndex;
    int endProtoIndex = url.indexOf("//");

    while ((upDirIndex=url.indexOf("/../")) != -1)
    {
       end = url.substring(upDirIndex+4);
       begin = url.substring(0, upDirIndex);

       if (begin.indexOf("/", endProtoIndex+2) != -1)      
         begin = url.substring(0, begin.lastIndexOf("/")+1);
       else
         begin += "/";

       url = begin.concat(end);
    }

    return url;
  }
}
TOP

Related Classes of org.jasig.portal.utils.AbsoluteURLFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.