/**
* ConnectionDetailsScreen.java
*
* Copyright � 1998-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.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.rim.samples.device.networkapidemo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connection;
import javax.microedition.io.InputConnection;
import javax.microedition.io.OutputConnection;
import net.rim.device.api.browser.field2.BrowserField;
import net.rim.device.api.browser.field2.BrowserFieldConfig;
import net.rim.device.api.io.transport.ConnectionDescriptor;
import net.rim.device.api.io.transport.TransportInfo;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.MainScreen;
/**
* A screen showing connection details: transport, URL and results of a
* connection request. Clicking the "Render HTML" button shows the content of an
* HTML response in a BrowserField. Clicking the "Render RAW" button shows the
* content of a response as text.
*/
public final class ConnectionDetailsScreen extends MainScreen {
// Displays text results from the server
private final RichTextField _contentsField;
// URL requested
private final String _originalUrl;
// Triggers rendering of results from the server in a BrowserField
private final ButtonField _renderBtn;
// Parses HTML results from the server and displays them like a browser
private final BrowserField _browserField;
private boolean _renderRaw;
private final UiApplication _uiApp;
/**
* Creates a new ConnectionDetailsScreen object
*
* @param connectionDescriptor
* The ConnectionDescriptor used to connect
* @param originalUrl
* The original URL used to connect
*/
public ConnectionDetailsScreen(
final ConnectionDescriptor connectionDescriptor,
final String originalUrl) {
_originalUrl = originalUrl;
setTitle("Connection Details");
final BrowserFieldConfig browserFieldConfig = new BrowserFieldConfig();
// Enable caret navigation mode
browserFieldConfig.setProperty(BrowserFieldConfig.NAVIGATION_MODE,
BrowserFieldConfig.NAVIGATION_MODE_NODE);
// Disable JavaScript
browserFieldConfig.setProperty(BrowserFieldConfig.JAVASCRIPT_ENABLED,
Boolean.FALSE);
_browserField = new BrowserField(browserFieldConfig);
add(new SeparatorField());
// Get the URL from the ConnectionDescriptor
final String url = getUrl(connectionDescriptor);
// Display transport and URL
add(new LabelField("Transport: "
+ TransportInfo.getTransportTypeName(connectionDescriptor
.getTransportDescriptor().getTransportType())));
add(new LabelField("Url: " + url));
add(new SeparatorField());
// Initialize button for displaying results in a browser field
// or as raw HTML.
_renderBtn =
new ButtonField("Render HTML", ButtonField.NEVER_DIRTY
| Field.FIELD_HCENTER | ButtonField.CONSUME_CLICK);
_renderBtn.setEnabled(false);
_renderBtn.setChangeListener(new FieldChangeListener() {
/**
* @see FieldChangeListener#fieldChanged(Field, int)
*/
public void fieldChanged(final Field field, final int context) {
if (_renderRaw) {
renderRawContents();
} else {
renderHtmlContents();
}
}
});
add(_renderBtn);
add(new SeparatorField());
// Display "Fetching content..." message below the buttons
_contentsField =
new RichTextField("Fetching content...", Field.NON_FOCUSABLE);
add(_contentsField);
add(new SeparatorField());
// Start thread to read content
final ContentReaderThread contentReader =
new ContentReaderThread(url, connectionDescriptor);
contentReader.start();
_uiApp = UiApplication.getUiApplication();
}
/**
* Displays a response received from a connection
*
* @param content
* The String response of a connection
*/
public void showContents(final String content) {
_uiApp.invokeLater(new Runnable() {
/**
* @see Runnable#run()
*/
public void run() {
_contentsField.setText(content);
}
});
}
/**
* Renders a response in a <code>BrowserField</code>
*/
public void renderHtmlContents() {
_uiApp.invokeLater(new Runnable() {
/**
* @see Runnable#run()
*/
public void run() {
// Remove text results from the screen
delete(_contentsField);
// Render HTML results
_browserField.displayContent(_contentsField.getText(),
_originalUrl);
add(_browserField);
// Update button label from "Render HTML" to "Render RAW"
_renderBtn.setLabel("Render RAW");
_renderRaw = true;
}
});
}
/**
* Renders a response in a RichTextField
*/
public void renderRawContents() {
_uiApp.invokeLater(new Runnable() {
/**
* @see Runnable#run()
*/
public void run() {
// Remove HTML results from the screen
delete(_browserField);
// Displays text results
add(_contentsField);
// Update button label from "Render RAW" to "Render HTML"
_renderBtn.setLabel("Render HTML");
_renderRaw = false;
}
});
}
/**
* Retrieves URL from ConnectionDesciptor
*
* @param connectionDescriptor
* The ConnectionDesciptor used to connect
* @return URL String
*/
private static String
getUrl(final ConnectionDescriptor connectionDescriptor) {
if (connectionDescriptor == null) {
return null;
}
return connectionDescriptor.getUrl().toLowerCase();
}
/**
* A Thread class which opens a connection to a given URL and reads the
* server's results
*/
private final class ContentReaderThread extends Thread {
private final String _url;
private final ConnectionDescriptor _connectionDescriptor;
/**
* Creates a new ContentReaderThread object
*
* @param url
* The URL to connect to
* @param connectionDescriptor
* Stores information about a <code>Connection</code>
*/
ContentReaderThread(final String url,
final ConnectionDescriptor connectionDescriptor) {
_url = url;
_connectionDescriptor = connectionDescriptor;
}
/**
* @see Thread#run()
*/
public void run() {
String result = "";
OutputStream os = null;
InputStream is = null;
final Connection connection = _connectionDescriptor.getConnection();
try {
// Check if URL starts with "socket", "tls", or "ssl" protocols.
// In this case send a HTTP GET request before opening
// InputStream
if (_url.startsWith("socket://") || _url.startsWith("tls://")
|| _url.startsWith("ssl://")) {
// Send HTTP GET to the server
final OutputConnection outputConn =
(OutputConnection) connection;
os = outputConn.openOutputStream();
final String getCommand =
"GET " + "/" + " HTTP/1.0\r\n\r\n";
os.write(getCommand.getBytes());
os.flush();
}
// Get InputConnection and read the server's response
final InputConnection inputConn = (InputConnection) connection;
is = inputConn.openInputStream();
final byte[] data =
net.rim.device.api.io.IOUtilities.streamToBytes(is);
result = new String(data);
is.close();
_renderBtn.setEnabled(true);
} catch (final Exception e) {
result = "ERROR fetching content: " + e.toString();
_renderBtn.setEnabled(false);
} finally {
// Close OutputStream
if (os != null) {
try {
os.close();
} catch (final IOException e) {
}
}
// Close InputStream
if (is != null) {
try {
is.close();
} catch (final IOException e) {
}
}
// Close InputStream
try {
connection.close();
} catch (final IOException ioe) {
}
}
// Show a response received from a connection or an error
showContents(result);
}
}
}