Package blackberry.web.widget.bf

Source Code of blackberry.web.widget.bf.WidgetRequestController

/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed 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 blackberry.web.widget.bf;

import java.io.IOException;

import javax.microedition.io.HttpConnection;
import javax.microedition.io.InputConnection;

import net.rim.blackberry.api.browser.Browser;
import net.rim.blackberry.api.browser.BrowserSession;
import net.rim.device.api.browser.field2.BrowserField;
import net.rim.device.api.browser.field2.BrowserFieldRequest;
import net.rim.device.api.browser.field2.BrowserFieldResponse;
import net.rim.device.api.browser.field2.ProtocolController;
import net.rim.device.api.io.MIMETypeAssociations;
import net.rim.device.api.io.URI;
import net.rim.device.api.web.WidgetAccess;
import net.rim.device.api.web.WidgetConfig;
import blackberry.common.util.StringUtilities;
import blackberry.core.IJSExtension;
import blackberry.core.JSExtensionRequest;
import blackberry.core.JSExtensionResponse;
import blackberry.web.widget.MemoryMaid;
import blackberry.web.widget.auth.Authenticator;
import blackberry.web.widget.device.DeviceInfo;
import blackberry.web.widget.exception.MediaHandledException;
import blackberry.web.widget.impl.WidgetConfigImpl;
import blackberry.web.widget.impl.WidgetException;
import blackberry.web.widget.policy.WidgetPolicy;
import blackberry.web.widget.policy.WidgetPolicyFactory;
import blackberry.web.widget.bf.HTTPResponseStatus;

/**
*
*/
public class WidgetRequestController extends ProtocolController {
    private WidgetConfig _widgetConfig;
    private WidgetPolicy _widgetPolicy;
    private boolean _hasMultiAccess;
    private BrowserField _browserField;

    /**
     * Constructor.
     */
    public WidgetRequestController( BrowserField bf, WidgetConfig config ) {
        super( bf );
        _widgetConfig = config;
        _widgetPolicy = WidgetPolicyFactory.getPolicy();

        // Set BF handle.
        _browserField = bf;

        // Support for *
        if( _widgetConfig instanceof WidgetConfigImpl ) {
            _hasMultiAccess = ( (WidgetConfigImpl) _widgetConfig ).allowMultiAccess();
        }

    }

    /**
     * @see net.rim.device.api.browser.field2.BrowserFieldController
     */

    public void handleNavigationRequest( BrowserFieldRequest request ) throws Exception {
        WidgetAccess access = _widgetPolicy.getElement( request.getURL(), _widgetConfig.getAccessList() );
        if( access == null && !_hasMultiAccess ) {
            if( !DeviceInfo.isBlackBerry6() ) {
                _browserField.getHistory().go( -1 );
            }
            throw new WidgetException( WidgetException.ERROR_WHITELIST_FAIL, request.getURL() );

        }

        BrowserFieldScreen bfScreen = ( (BrowserFieldScreen) _browserField.getScreen() );

        // Launch the browser if BF2 cannot handle the mime type
        if( !openWithBrowser( request ) ) {
            // Determine the MIME type of the url
            String contentType = MIMETypeAssociations.getMIMEType( request.getURL() );

            // Normalize and strip off parameters.
            String normalizedContentType = MIMETypeAssociations.getNormalizedType( contentType );

            // Determine protocol
            String protocol = request.getProtocol();

            bfScreen.getPageManager().setGoingBackSafe( false );
            InputConnection ic = null;
            try {
                if( bfScreen.getCacheManager() != null && bfScreen.getCacheManager().isRequestCacheable( request ) ) {
                    if( bfScreen.getCacheManager().hasCache( request.getURL() )
                            && !bfScreen.getCacheManager().hasCacheExpired( request.getURL() ) ) {
                        ic = bfScreen.getCacheManager().getCache( request.getURL() );
                    } else {
                        ic = _browserField.getConnectionManager().makeRequest( request );
                        if( ic instanceof HttpConnection ) {
                            HttpConnection response = (HttpConnection) ic;
                            if( bfScreen.getCacheManager().isResponseCacheable( response ) ) {
                                ic = bfScreen.getCacheManager().createCache( request.getURL(), response );

                            }
                        }
                    }

                    ic = processAuthentication( ic, request );

                    _browserField.displayContent( ic, request.getURL() );
                } else {

                    // Check whether authentication is required
                    if( isHttpProtocol( request ) ) {
                        // Only HTTP/HTTPS can use the API to receive the response
                        ic = _browserField.getConnectionManager().makeRequest( request );
                        ic = processAuthentication( ic, request );

                        _browserField.displayContent( ic, request.getURL() );
                    } else {
                        super.handleNavigationRequest( request );
                    }

                }

                if( !bfScreen.getPageManager().isRedirectableNavigation( protocol ) ) {
                    // The navigation won't redirect
                    bfScreen.getPageManager().clearFlags();

                    if( !bfScreen.getPageManager().isLocalTextHtml( normalizedContentType ) ) {
                        if( bfScreen.getPageManager().isLoadingScreenDisplayed() ) {
                            bfScreen.getPageManager().hideLoadingScreen();
                        }
                    }
                }

            } catch( Exception e ) {

                bfScreen.getPageManager().hideLoadingScreen();
                bfScreen.getPageManager().clearFlags();

                // Rethrow the Exception
                throw e;
            }
        }
   
        MemoryMaid mm = MemoryMaid.getInstance();
        if( mm != null ) {
            if( mm.isAlive() ) {
                mm.flagGC();
            } else {
                // Start the memory manager after our first page has been loaded
                mm.start();
            }
        }
    }

    /**
     * @see net.rim.device.api.browser.field2.BrowserFieldController
     */
    public InputConnection handleResourceRequest( BrowserFieldRequest request ) throws Exception {

        if( this._browserField == null ) {
            return new HTTPResponseStatus( HTTPResponseStatus.SC_SERVER_ERROR, request ).getResponse();
        }
        if( request.getURL().startsWith( "http://localhost:8472/" ) ) {
            URI requestURI = URI.create( request.getURL() );
            String[] splitPath = StringUtilities.split( requestURI.getPath(), "/" );
            String featureID = "";
            for( int i = 0; i < splitPath.length - 1; i++ ) {
                if( featureID == "" ) {
                    featureID = featureID + splitPath[ i ];
                } else {
                    featureID = featureID + "." + splitPath[ i ];
                }
            }
            Object ext = ( (WidgetConfigImpl) _widgetConfig ).getExtensionObjectForFeature( featureID );
            if( ext != null && ext instanceof IJSExtension ) {
                JSExtensionRequest req = new JSExtensionRequest( request.getURL(), request.getPostData(), request.getHeaders(),
                        ( (WidgetConfigImpl) _widgetConfig ).getFeatureTable() );
                JSExtensionResponse res = new JSExtensionResponse( request.getURL(), null, request.getHeaders() );
                try {
                    ( (IJSExtension) ext ).invoke( req, res );
                    return new BrowserFieldResponse( res.getURL(), res.getPostData(), res.getHeaders() );
                } catch( net.rim.device.api.web.WidgetException e ) {
                    // this block is reached if the method cannot be found within the extension
                    return new HTTPResponseStatus( HTTPResponseStatus.SC_NOT_IMPLEMENTED, request ).getResponse();
                }
            } else {
                if( ext == null ) {
                    return new HTTPResponseStatus( HTTPResponseStatus.SC_NOT_FOUND, request ).getResponse();
                } else if( !( ext instanceof IJSExtension ) ) {
                    return new HTTPResponseStatus( HTTPResponseStatus.SC_NOT_IMPLEMENTED, request ).getResponse();
                }
            }
        }
        WidgetAccess access = _widgetPolicy.getElement( request.getURL(), _widgetConfig.getAccessList() );
        if( access == null && !_hasMultiAccess ) {
            throw new WidgetException( WidgetException.ERROR_WHITELIST_FAIL, request.getURL() );
        }

        // In this event, only rtsp link needs to open browser
        if( request.getProtocol().equalsIgnoreCase( "rtsp" ) ) {
            openWithBrowser( request );
            return null;
        }

        BrowserFieldScreen bfScreen = ( (BrowserFieldScreen) _browserField.getScreen() );
        InputConnection ic = null;
        if( bfScreen.getCacheManager() != null && bfScreen.getCacheManager().isRequestCacheable( request ) ) {
            if( bfScreen.getCacheManager().hasCache( request.getURL() )
                    && !bfScreen.getCacheManager().hasCacheExpired( request.getURL() ) ) {
                ic = bfScreen.getCacheManager().getCache( request.getURL() );
            } else {
                ic = super.handleResourceRequest( request );
                if( ic instanceof HttpConnection ) {
                    HttpConnection response = (HttpConnection) ic;
                    if( bfScreen.getCacheManager().isResponseCacheable( response ) ) {
                        ic = bfScreen.getCacheManager().createCache( request.getURL(), response );
                    }
                }
            }
        } else {
            ic = super.handleResourceRequest( request );
        }
        ic = processAuthentication( ic, request );
        return ic;
    }

    /**
     * Performs authentication checks and requests credentials when needed
     */
    private InputConnection processAuthentication( InputConnection ic, BrowserFieldRequest request ) throws Exception {

        // Check if Basic authentication is required to access the resource
        boolean authenticationIsNeeded = false;
        while( isAuthenticationNeeded( ic, request ) ) {
            authenticationIsNeeded = true;
            BrowserFieldRequest authenticationReq = Authenticator.getAuthenticationRequest( (HttpConnection) ic, request );
            if( authenticationReq == request ) {
                break;
            }
            ic = super.handleResourceRequest( authenticationReq );
        }

        // If credentials are needed and they are correct, set them verified
        if( authenticationIsNeeded && !isHTTPError( ic ) ) {
            Authenticator.verifyCredential( (HttpConnection) ic );
        }

        return ic;
    }

    /**
     * Check if authentication is needed by checking the response code.
     *
     * @param icResponse
     * @param request
     * @return
     */
    private static boolean isAuthenticationNeeded( InputConnection icResponse, BrowserFieldRequest request ) {
        if( icResponse instanceof HttpConnection && isHttpProtocol( request ) ) {
            HttpConnection hcResponse = (HttpConnection) icResponse;
            try {
                int responseCode = hcResponse.getResponseCode();
                return HttpConnection.HTTP_UNAUTHORIZED == responseCode;
            } catch( IOException e ) {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * Check if the request uses the HTTP protocol
     *
     * @param request
     * @return
     */
    private static boolean isHttpProtocol( BrowserFieldRequest request ) {
        String protocol = request.getProtocol();
        return ( protocol.equalsIgnoreCase( "http" ) || protocol.equalsIgnoreCase( "https" ) );
    }

    /**
     * Check the connection for an error response code
     *
     * @param ic
     * @return
     */
    private static boolean isHTTPError( InputConnection ic ) {
        if( ic instanceof HttpConnection ) {
            try {
                HttpConnection hcResponse = (HttpConnection) ic;
                int responseCode = hcResponse.getResponseCode();
                return ( responseCode >= 400 && responseCode < 600 );
            } catch( IOException e ) {
                return true;
            }
        } else {
            return true;
        }
    }

    // Method to check if the browser needs to be launched to handle the file.
    private boolean openWithBrowser( BrowserFieldRequest request ) throws Exception {
        BrowserFieldScreen bfScreen = ( (BrowserFieldScreen) _browserField.getScreen() );

        // Determine the MIME type of the url
        String contentType = MIMETypeAssociations.getMIMEType( request.getURL() );

        // Normalize and strip off parameters.
        String normalizedContentType = MIMETypeAssociations.getNormalizedType( contentType );

        // Determine protocol
        String protocol = request.getProtocol();

        // Launch the browser if BF2 cannot handle the mime type
        if( openWithBrowser( normalizedContentType, protocol, request.getURL() ) ) {

            invokeBrowser( request.getURL() );

            // Reset the loading screen flags to ensure that the back button is enabled after the invoke
            bfScreen.getPageManager().clearFlags();

            if( DeviceInfo.isBlackBerry6() ) {
                // Throw a special type of exception that will prevent the history from being updated
                throw new MediaHandledException();
            } else {
                // On 5.0 devices we can simply go back once to counter the history updating before this.
                _browserField.getHistory().go( -1 );
            }
            return true;
        } else {
            return false;
        }
    }

    // Method to check if the browser needs to be launched to handle the file.
    private boolean openWithBrowser( String mimeType, String protocol, String url ) {
        // rtsp links should open in the browser. �BF2 does not support the protocol
        if( protocol.equalsIgnoreCase( "rtsp" ) ) {
            return true;
        }

        if( mimeType != null ) {

            // Determine media type.
            int mediaType = MIMETypeAssociations.getMediaTypeFromMIMEType( mimeType );

            // Allow all local media to be handled by BF2.
            // Even if it is not supported by BF2 yet.
            if( protocol.equalsIgnoreCase( "local" ) ) {
                return false;
            }

            // List of types we don't want BF2 to handle.
            if( ( mediaType == MIMETypeAssociations.MEDIA_TYPE_AUDIO ) || ( mediaType == MIMETypeAssociations.MEDIA_TYPE_VIDEO )
                    || ( mediaType == MIMETypeAssociations.MEDIA_TYPE_PLAY_LIST )
                    || ( mediaType == MIMETypeAssociations.MEDIA_TYPE_APPLICATION )
                    || ( mediaType == MIMETypeAssociations.MEDIA_TYPE_UNKNOWN ) ) {
                return true;
            }
        }

        // If the type was null, check the file extension for .zip or .exe
        // Mark .zip and .exe to be unsupported by BF2 so that the browser will
        // be launched
        // Local files must be opened by BF2 all the time since the browser has
        // no access to those internal files
        if( checkFileExtension( url ) && !protocol.equalsIgnoreCase( "local" ) ) {
            return true;
        } else {
            return false;
        }
    }

    // Checks the file extension for special types.
    private boolean checkFileExtension( String url ) {

        boolean isMarked = false;

        // Check for .zip
        if( url.endsWith( ".zip" ) ) {
            isMarked = true;
        }
        // Check for .exe
        else if( url.endsWith( ".exe" ) ) {
            isMarked = true;
        }
        // Check for .wpd
        else if( url.endsWith( ".wpd" ) ) {
            isMarked = true;
        }

        // Return the value. False means it is not a special extension
        return isMarked;
    }

    // Invokes the browser on the given URL
    private void invokeBrowser( String url ) {
        BrowserSession bs = null;
        bs = Browser.getDefaultSession();
        bs.displayPage( url );
    }
}
TOP

Related Classes of blackberry.web.widget.bf.WidgetRequestController

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.