This checkin implements a response header listener feature.

I have changed the usage contract of the DocumentLoadListener slightly.
Prior to this checkin, calling getEventData() on the DocumentLoadEvent
passed in to your eventDispatched() method returned the URI to which the
event applies.

Now the getEventData() returns a Map.  You must look up the "URI" key to
find the URI to which the event applies.  If your listener is an
instance of PageInfoListener, and your event mask is
END_URL_LOAD_EVENT_MASK, your Map will have an additional entry under
the key "headers".  This entry is another Map representing the response
headers.

DocumentLoadListener:

 * <p>The <code>eventDispatched()</code> method is passed a {@link
 * DocumentLoadEvent} instance.  The <code>type</code> property of the
 * event will be one of the types defined as a <code>public static final
 * int</code> in <code>DocumentLoadEvent</code>.</p>
 *
 * <p>The <code>eventData</code> property of the
 * <code>DocumentLoadEvent</code> instance will be a
 * <code>java.util.Map</code>.  For all <code>EVENT_MASK</code> types in
 * <code>DocumentLoadEvent</code> the map will contain an entry under
 * the key "<code>URI</code>" without the quotes.  This will be the
 * fully qualified URI for the event.</p>
 *
 * <p>For the <code>PROGRESS_URL_LOAD_EVENT_MASK</code> there will be an
 * entry in the map for the key "<code>message</code>".  This will be
 * the progress message from the browser.</p>

PageInfoListener:

 * <p>This {@link DocumentLoadListener} subclass adds the ability to get
 * detailed information on each event. </p>
 *
 * <p>The <code>eventDispatched()</code> method is passed the same thing
 * as in the {@link DocumentLoadListener}.</p>
 *
 * <p>The <code>eventData</code> property of the
 * <code>DocumentLoadEvent</code> instance will be a
 * <code>java.util.Map</code>.  For the
 * <code>END_URL_LOAD_EVENT_MASK</code> type in
 * <code>DocumentLoadEvent</code> the map will contain an entry under
 * the key "<code>URI</code>" without the quotes.  This will be the
 * fully qualified URI for the event.  The map will also contain an
 * entry under the key "<code>headers</code>".  This entry will be a
 * <code>Map</code> of all the response headers.</p>


The next step will be to allow the same procedure to work to discover
the request headers.

Ed

A classes_spec/org/mozilla/webclient/PageInfoListener.java

- marker class for listenening for high fidelity page information.

A src_moz/EventRegistrationImpl.cpp

- add boolean property, capturePageInfo to turn on or off high fidelity
  page information collection.

M build-tests.xml

- add new test, DocumentLoadListenerTest

M build.xml

- added new JNI class, EventRegistrationImpl

M classes_spec/org/mozilla/webclient/CurrentPage2.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/CurrentPageImpl.java

- rollback previous API for headers discovery

M classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java

- pass thru the capturePageInfo property

- add URIToStringMap, currently not working.

M classes_spec/org/mozilla/webclient/test/EMWindow.java

- call toString() on the eventData, don't cast it to a String.

M src_moz/EmbedProgress.cpp
M src_moz/EmbedProgress.h

- leverage the nsIHttpHeaderVisitor interface to discover the response
  headers.

- add boolean property capturePageInfo

A src_moz/HttpHeaderVisitorImpl.cpp
A src_moz/HttpHeaderVisitorImpl.h

- copy the headers to a Properties object.

M src_moz/Makefile.in

- compile two new files:

+	EventRegistrationImpl.cpp \
+	HttpHeaderVisitorImpl.cpp \

M src_moz/NativeBrowserControl.cpp
M src_moz/NativeBrowserControl.h

- pass the NativeWrapperFactory to our Init() method

- add wrapperFactory getter.

M src_moz/WrapperFactoryImpl.cpp

- pass the nativeWrapperFactory to the NativeBrowserControl's Init method.

M src_share/jni_util.cpp
M src_share/jni_util.h

- new constants: URI, headers

R test/automated/src/classes/org/mozilla/webclient/CurrentPageTest.java

- not yet time for this one
A test/automated/src/classes/org/mozilla/webclient/DocumentLoadListenerTest.java

- exercise bare minimum functionality of PageInfoListener

M test/manual/src/classes/org/mozilla/webclient/test/TestBrowser.java

- print out headers.
This commit is contained in:
edburns%acm.org 2004-09-09 20:17:18 +00:00
Родитель 75da720177
Коммит cadd94c8f8
21 изменённых файлов: 624 добавлений и 152 удалений

Просмотреть файл

@ -160,8 +160,8 @@
<test name="org.mozilla.webclient.impl.wrapper_native.WrapperFactoryImplTest"/>
<test name="org.mozilla.webclient.impl.WebclientFactoryImplTest"/>
<test name="org.mozilla.webclient.NavigationTest"/>
<!-- <test name="org.mozilla.webclient.CurrentPageTest"/> -->
<test name="org.mozilla.webclient.HistoryTest"/>
<test name="org.mozilla.webclient.DocumentLoadListenerTest"/>
<!-- non running
<test name="org.mozilla.webclient.wrapper_native.gtk.TestGtkBrowserControlCanvas"/>
-->

Просмотреть файл

@ -124,7 +124,7 @@
<target name="compile.javah.headers" depends="compile.classes_spec,compile.javah.canvas.headers">
<javah destdir="${basedir}/src_share"
class="org.mozilla.webclient.impl.wrapper_native.BookmarksImpl,org.mozilla.webclient.impl.wrapper_native.ProfileManagerImpl,org.mozilla.webclient.impl.wrapper_native.PreferencesImpl,org.mozilla.webclient.impl.wrapper_native.CurrentPageImpl,org.mozilla.webclient.impl.wrapper_native.HistoryImpl,org.mozilla.webclient.impl.wrapper_native.WrapperFactoryImpl,org.mozilla.webclient.impl.wrapper_native.NavigationImpl,org.mozilla.webclient.impl.wrapper_native.RDFEnumeration,org.mozilla.webclient.impl.wrapper_native.RDFTreeNode,org.mozilla.webclient.impl.wrapper_native.ISupportsPeer,org.mozilla.webclient.impl.wrapper_native.WindowControlImpl,org.mozilla.webclient.impl.wrapper_native.NativeEventThread">
class="org.mozilla.webclient.impl.wrapper_native.BookmarksImpl,org.mozilla.webclient.impl.wrapper_native.ProfileManagerImpl,org.mozilla.webclient.impl.wrapper_native.PreferencesImpl,org.mozilla.webclient.impl.wrapper_native.CurrentPageImpl,org.mozilla.webclient.impl.wrapper_native.HistoryImpl,org.mozilla.webclient.impl.wrapper_native.WrapperFactoryImpl,org.mozilla.webclient.impl.wrapper_native.NavigationImpl,org.mozilla.webclient.impl.wrapper_native.RDFEnumeration,org.mozilla.webclient.impl.wrapper_native.RDFTreeNode,org.mozilla.webclient.impl.wrapper_native.ISupportsPeer,org.mozilla.webclient.impl.wrapper_native.WindowControlImpl,org.mozilla.webclient.impl.wrapper_native.NativeEventThread,org.mozilla.webclient.impl.wrapper_native.EventRegistrationImpl">
<classpath refid="compile.classpath"/>
</javah>
</target>

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
@ -23,8 +23,6 @@
package org.mozilla.webclient;
import java.util.Map;
public interface CurrentPage2 extends CurrentPage
{
@ -37,9 +35,5 @@ public interface CurrentPage2 extends CurrentPage
public void print();
public void printPreview(boolean preview);
public Map getRequestHeaders();
public Map getResponseHeaders();
}
// end of interface CurrentPage2

Просмотреть файл

@ -22,6 +22,25 @@
package org.mozilla.webclient;
/**
* <p>The <code>eventDispatched()</code> method is passed a {@link
* DocumentLoadEvent} instance. The <code>type</code> property of the
* event will be one of the types defined as a <code>public static final
* int</code> in <code>DocumentLoadEvent</code>.</p>
*
* <p>The <code>eventData</code> property of the
* <code>DocumentLoadEvent</code> instance will be a
* <code>java.util.Map</code>. For all <code>EVENT_MASK</code> types in
* <code>DocumentLoadEvent</code> the map will contain an entry under
* the key "<code>URI</code>" without the quotes. This will be the
* fully qualified URI for the event.</p>
*
* <p>For the <code>PROGRESS_URL_LOAD_EVENT_MASK</code> there will be an
* entry in the map for the key "<code>message</code>". This will be
* the progress message from the browser.</p>
*
*/
public interface DocumentLoadListener extends WebclientEventListener {
}

Просмотреть файл

@ -0,0 +1,46 @@
/* -*- Mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is RaptorCanvas.
*
* The Initial Developer of the Original Code is Kirk Baker and
* Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are
* Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All
* Rights Reserved.
*
* Contributor(s): Ed Burns <edburns@acm.org>
*/
package org.mozilla.webclient;
/**
* <p>This {@link DocumentLoadListener} subclass adds the ability to get
* detailed information on each event. </p>
*
* <p>The <code>eventDispatched()</code> method is passed the same thing
* as in the {@link DocumentLoadListener}.</p>
*
* <p>The <code>eventData</code> property of the
* <code>DocumentLoadEvent</code> instance will be a
* <code>java.util.Map</code>. For the
* <code>END_URL_LOAD_EVENT_MASK</code> type in
* <code>DocumentLoadEvent</code> the map will contain an entry under
* the key "<code>URI</code>" without the quotes. This will be the
* fully qualified URI for the event. The map will also contain an
* entry under the key "<code>headers</code>". This entry will be a
* <code>Map</code> of all the response headers.</p>
*
*/
public interface PageInfoListener extends DocumentLoadListener {
}

Просмотреть файл

@ -32,7 +32,6 @@ import org.mozilla.webclient.WindowControl;
import org.mozilla.webclient.impl.WrapperFactory;
import java.util.Properties;
import java.util.Map;
import java.io.*;
import java.net.*;
@ -293,17 +292,6 @@ public void printPreview(boolean preview)
}
}
public Map getRequestHeaders()
{
return null;
}
public Map getResponseHeaders()
{
return null;
}
//
// Native methods
//
@ -340,4 +328,21 @@ native public void nativePrint(int webShellPtr);
native public void nativePrintPreview(int webShellPtr, boolean preview);
// ----VERTIGO_TEST_START
//
// Test methods
//
public static void main(String [] args)
{
Assert.setEnabled(true);
Log.setApplicationName("CurrentPageImpl");
Log.setApplicationVersion("0.0");
Log.setApplicationVersionDate("$Id: CurrentPageImpl.java,v 1.7 2004-09-09 20:17:16 edburns%acm.org Exp $");
}
// ----VERTIGO_TEST_END
} // end of class CurrentPageImpl

Просмотреть файл

@ -29,7 +29,10 @@ import org.mozilla.util.ParameterCheck;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Iterator;
import java.util.Set;
import java.util.Collection;
import org.mozilla.webclient.BrowserControl;
import org.mozilla.webclient.BrowserControlCanvas;
@ -37,6 +40,7 @@ import org.mozilla.webclient.EventRegistration2;
import org.mozilla.webclient.impl.WrapperFactory;
import org.mozilla.webclient.DocumentLoadEvent;
import org.mozilla.webclient.DocumentLoadListener;
import org.mozilla.webclient.PageInfoListener;
import org.mozilla.webclient.NewWindowEvent;
import org.mozilla.webclient.NewWindowListener;
import java.awt.event.MouseListener;
@ -116,6 +120,16 @@ public void addDocumentLoadListener(DocumentLoadListener listener)
getWrapperFactory().verifyInitialized();
synchronized(documentLoadListeners) {
if (listener instanceof PageInfoListener) {
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable(){
public Object run() {
nativeSetCapturePageInfo(getNativeBrowserControl(),
true);
return null;
}
});
}
documentLoadListeners.add(listener);
}
}
@ -124,9 +138,20 @@ public void removeDocumentLoadListener(DocumentLoadListener listener)
{
ParameterCheck.nonNull(listener);
getWrapperFactory().verifyInitialized();
synchronized(documentLoadListeners) {
documentLoadListeners.remove(listener);
if (0 == documentLoadListeners.size()) {
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable(){
public Object run() {
nativeSetCapturePageInfo(getNativeBrowserControl(),
false);
return null;
}
});
}
}
}
@ -244,7 +269,9 @@ void nativeEventOccurred(String targetClassName, long eventType,
WebclientEvent event = null;
if (DocumentLoadListener.class.getName().equals(targetClassName)) {
event = new DocumentLoadEvent(this, eventType, eventData);
event = new DocumentLoadEvent(this, eventType,
// PENDING(edburns: new URIToStringMap((Map)eventData));
eventData);
}
else if (MouseListener.class.getName().equals(targetClassName)) {
// We create a plain vanilla WebclientEvent, which the
@ -265,6 +292,9 @@ void nativeEventOccurred(String targetClassName, long eventType,
eventPump.V();
}
private native void nativeSetCapturePageInfo(int webShellPtr,
boolean newState);
public class BrowserToJavaEventPump extends Thread {
private boolean keepRunning = false;
@ -349,5 +379,78 @@ public class BrowserToJavaEventPump extends Thread {
} // end of class BrowserToJavaEventPump
class URIToStringMap extends Object implements Map {
private Map map = null;
URIToStringMap(Map yourMap) {
map = yourMap;
}
public String toString() {
Object result = null;
if (null == map || null == (result = map.get("URI"))) {
result = "";
}
return result.toString();
}
public void clear() {
throw new UnsupportedOperationException();
}
public boolean containsKey(Object key) {
return map.containsKey(key);
}
public boolean containsValue(Object value) {
return map.containsValue(value);
}
public Set entrySet() {
return map.entrySet();
}
public boolean equals(Object o) {
return map.equals(o);
}
public Object get(Object key) {
return map.get(key);
}
public int hashCode() {
return map.hashCode();
}
public boolean isEmpty() {
return map.isEmpty();
}
public Set keySet() {
return map.keySet();
}
public Object put(Object key, Object value) {
return map.put(key, value);
}
public void putAll(Map t) {
map.putAll(t);
}
public Object remove(Object key) {
return map.remove(key);
}
public int size() {
return map.size();
}
public Collection values() {
return map.values();
}
}
} // end of class EventRegistrationImpl

Просмотреть файл

@ -59,7 +59,7 @@ import java.io.FileInputStream;
* This is a test application for using the BrowserControl.
*
* @version $Id: EMWindow.java,v 1.44 2003-06-09 20:05:36 edburns%acm.org Exp $
* @version $Id: EMWindow.java,v 1.45 2004-09-09 20:17:16 edburns%acm.org Exp $
*
* @see org.mozilla.webclient.BrowserControlFactory
@ -719,7 +719,7 @@ public void eventDispatched(WebclientEvent event)
case ((int) DocumentLoadEvent.START_DOCUMENT_LOAD_EVENT_MASK):
stopButton.setEnabled(true);
refreshButton.setEnabled(true);
currentURL = (String) event.getEventData();
currentURL = event.getEventData().toString();
System.out.println("debug: edburns: Currently Viewing: " +
currentURL);
statusLabel.setText("Starting to load " + currentURL);
@ -754,11 +754,11 @@ public void eventDispatched(WebclientEvent event)
statusLabel.setText(status);
break;
case ((int) DocumentLoadEvent.START_URL_LOAD_EVENT_MASK):
status = (String) event.getEventData();
status = event.getEventData().toString();
urlStatusLabel.setText("startURL: " + status);
break;
case ((int) DocumentLoadEvent.END_URL_LOAD_EVENT_MASK):
status = (String) event.getEventData();
status = event.getEventData().toString();
urlStatusLabel.setText(" endURL: " + status);
break;
}

Просмотреть файл

@ -33,9 +33,11 @@
#include "NativeBrowserControl.h"
#include "HttpHeaderVisitorImpl.h"
#include "ns_globals.h" // for prLogModuleInfo
EmbedProgress::EmbedProgress(void)
EmbedProgress::EmbedProgress(void) : mCapturePageInfo(JNI_FALSE)
{
mOwner = nsnull;
mEventRegistration = nsnull;
@ -84,6 +86,13 @@ EmbedProgress::SetEventRegistration(jobject yourEventRegistration)
return rv;
}
nsresult
EmbedProgress::SetCapturePageInfo(jboolean newState)
{
mCapturePageInfo = newState;
return NS_OK;
}
NS_IMETHODIMP
EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
@ -91,12 +100,26 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress,
nsresult aStatus)
{
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
nsXPIDLCString uriString;
RequestToURIString(aRequest, getter_Copies(uriString));
const char * uriCStr = (const char *) uriString;
jstring uriJstr = ::util_NewStringUTF(env, (nsnull != uriCStr
? uriCStr : ""));
// don't report "about:" URL events.
if (uriString && 5 < uriString.Length() &&
0 == strncmp("about:", uriCStr, 6)) {
return NS_OK;
}
jstring uriJstr = (jstring) ::util_NewGlobalRef(env,
::util_NewStringUTF(env, (nsnull != uriCStr
? uriCStr : "")));
jobject properties = ::util_NewGlobalRef(env,
::util_CreatePropertiesObject(env,
(jobject)
&(mOwner->GetWrapperFactory()->shareContext)));
::util_StoreIntoPropertiesObject(env, properties, URI_VALUE, uriJstr,
(jobject)
&(mOwner->GetWrapperFactory()->shareContext));
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: URI: %s\n",
@ -111,31 +134,27 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress,
if ((aStateFlags & STATE_IS_NETWORK) &&
(aStateFlags & STATE_START)) {
if (channel) {
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: have nsIHttpChannel at START_DOCUMENT_LOAD\n"));
}
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: START_DOCUMENT_LOAD\n"));
util_SendEventToJava(nsnull,
mEventRegistration,
DOCUMENT_LOAD_LISTENER_CLASSNAME,
DocumentLoader_maskValues[START_DOCUMENT_LOAD_EVENT_MASK],
uriJstr);
properties);
}
// and for stop, too
if ((aStateFlags & STATE_IS_NETWORK) &&
(aStateFlags & STATE_STOP)) {
if (channel) {
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: have nsIHttpChannel at END_DOCUMENT_LOAD\n"));
}
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: END_DOCUMENT_LOAD\n"));
util_SendEventToJava(nsnull,
mEventRegistration,
DOCUMENT_LOAD_LISTENER_CLASSNAME,
DocumentLoader_maskValues[END_DOCUMENT_LOAD_EVENT_MASK],
uriJstr);
properties);
}
@ -143,22 +162,39 @@ EmbedProgress::OnStateChange(nsIWebProgress *aWebProgress,
// request states
//
if ((aStateFlags & STATE_START) && (aStateFlags & STATE_IS_REQUEST)) {
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: START_URL_LOAD\n"));
util_SendEventToJava(nsnull,
mEventRegistration,
DOCUMENT_LOAD_LISTENER_CLASSNAME,
DocumentLoader_maskValues[START_URL_LOAD_EVENT_MASK],
uriJstr);
properties);
}
if ((aStateFlags & STATE_STOP) && (aStateFlags & STATE_IS_REQUEST)) {
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStateChange: END_URL_LOAD\n"));
if (channel && mCapturePageInfo) {
HttpHeaderVisitorImpl *visitor =
new HttpHeaderVisitorImpl(env,
properties, (jobject)
&(mOwner->GetWrapperFactory()->shareContext));
channel->VisitResponseHeaders(visitor);
delete visitor;
}
util_SendEventToJava(nsnull,
mEventRegistration,
DOCUMENT_LOAD_LISTENER_CLASSNAME,
DocumentLoader_maskValues[END_URL_LOAD_EVENT_MASK],
uriJstr);
properties);
}
::util_DeleteStringUTF(env, uriJstr);
// ::util_DestroyPropertiesObject(env, properties, nsnull);
// ::util_DeleteStringUTF(env, uriJstr);
return NS_OK;
}
@ -174,10 +210,31 @@ EmbedProgress::OnProgressChange(nsIWebProgress *aWebProgress,
nsXPIDLCString uriString;
RequestToURIString(aRequest, getter_Copies(uriString));
const char * uriCStr = (const char *) uriString;
PRInt32 percentComplete = 0;
nsCAutoString name;
nsAutoString autoName;
nsresult rv = NS_OK;
// don't report "about:" URL events.
if (uriString && 5 < uriString.Length() &&
0 == strncmp("about:", (const char *) uriString, 6)) {
return NS_OK;
}
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
jstring uriJstr = (jstring) ::util_NewGlobalRef(env,
::util_NewStringUTF(env, (nsnull != uriCStr
? uriCStr : "")));
jobject properties = ::util_NewGlobalRef(env,
::util_CreatePropertiesObject(env,
(jobject)
&(mOwner->GetWrapperFactory()->shareContext)));
::util_StoreIntoPropertiesObject(env, properties, URI_VALUE, uriJstr,
(jobject)
&(mOwner->GetWrapperFactory()->shareContext));
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnProgressChange: URI: %s\n\taCurSelfProgress: %d\n\taMaxSelfProgress: %d\n\taCurTotalProgress: %d\n\taMaxTotalProgress: %d\n",
@ -199,19 +256,19 @@ EmbedProgress::OnProgressChange(nsIWebProgress *aWebProgress,
autoName.AppendInt(percentComplete);
autoName.AppendWithConversion("%");
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
jstring msgJStr = (jstring) ::util_NewGlobalRef(env,
::util_NewString(env, autoName.get(), autoName.Length()));
jstring msgJStr = ::util_NewString(env, autoName.get(), autoName.Length());
::util_StoreIntoPropertiesObject(env, properties, MESSAGE_VALUE, msgJStr,
(jobject)
&(mOwner->GetWrapperFactory()->shareContext));
util_SendEventToJava(nsnull,
mEventRegistration,
DOCUMENT_LOAD_LISTENER_CLASSNAME,
DocumentLoader_maskValues[PROGRESS_URL_LOAD_EVENT_MASK],
msgJStr);
properties);
if (msgJStr) {
::util_DeleteString(env, msgJStr);
}
return NS_OK;
}
@ -247,8 +304,29 @@ EmbedProgress::OnStatusChange(nsIWebProgress *aWebProgress,
nsXPIDLCString uriString;
RequestToURIString(aRequest, getter_Copies(uriString));
jstring msgJstr = ::util_NewString(env, aMessage,
nsCRT::strlen(aMessage));
const char * uriCStr = (const char *) uriString;
// don't report "about:" URL events.
if (uriString && 5 < uriString.Length() &&
0 == strncmp("about:", uriString, 6)) {
return NS_OK;
}
jstring uriJstr = (jstring) ::util_NewGlobalRef(env,
::util_NewStringUTF(env, (nsnull != uriCStr
? uriCStr : "")));
jobject properties = ::util_NewGlobalRef(env,
::util_CreatePropertiesObject(env,
(jobject)
&(mOwner->GetWrapperFactory()->shareContext)));
::util_StoreIntoPropertiesObject(env, properties, URI_VALUE, uriJstr,
(jobject)
&(mOwner->GetWrapperFactory()->shareContext));
jstring msgJstr = (jstring) ::util_NewGlobalRef(env,
::util_NewString(env, aMessage,
nsCRT::strlen(aMessage)));
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnStatusChange: URI: %s\n",
@ -258,11 +336,7 @@ EmbedProgress::OnStatusChange(nsIWebProgress *aWebProgress,
mEventRegistration,
DOCUMENT_LOAD_LISTENER_CLASSNAME,
DocumentLoader_maskValues[STATUS_URL_LOAD_EVENT_MASK],
msgJstr);
if (msgJstr) {
::util_DeleteString(env, msgJstr);
}
properties);
return NS_OK;
}
@ -274,6 +348,12 @@ EmbedProgress::OnSecurityChange(nsIWebProgress *aWebProgress,
{
nsXPIDLCString uriString;
RequestToURIString(aRequest, getter_Copies(uriString));
// don't report "about:" URL events.
if (uriString && 5 < uriString.Length() &&
0 == strncmp("about:", (const char *) uriString, 6)) {
return NS_OK;
}
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("EmbedProgress::OnSecurityChange: URI: %s\n",

Просмотреть файл

@ -40,6 +40,8 @@ class EmbedProgress : public nsIWebProgressListener,
nsresult SetEventRegistration(jobject eventRegistration);
nsresult SetCapturePageInfo(jboolean newState);
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBPROGRESSLISTENER
@ -51,6 +53,8 @@ class EmbedProgress : public nsIWebProgressListener,
NativeBrowserControl *mOwner;
jobject mEventRegistration;
jboolean mCapturePageInfo;
};
#endif /* __EmbedProgress_h */

Просмотреть файл

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is RaptorCanvas.
*
* The Initial Developer of the Original Code is Kirk Baker and
* Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are
* Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All
* Rights Reserved.
*
* Contributor(s): Kirk Baker <kbaker@eb.com>
* Ian Wilkinson <iw@ennoble.com>
* Mark Lin <mark.lin@eng.sun.com>
* Mark Goddard
* Ed Burns <edburns@acm.org>
* Ashutosh Kulkarni <ashuk@eng.sun.com>
*/
#include "org_mozilla_webclient_impl_wrapper_0005fnative_EventRegistrationImpl.h"
#include "ns_util.h"
#include "NativeBrowserControl.h"
#include "EmbedProgress.h"
JNIEXPORT void JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_EventRegistrationImpl_nativeSetCapturePageInfo
(JNIEnv *env, jobject obj, jint nativeBCPtr, jboolean newState)
{
NativeBrowserControl* nativeBrowserControl = (NativeBrowserControl *) nativeBCPtr;
nativeBrowserControl->mProgress->SetCapturePageInfo(newState);
}

Просмотреть файл

@ -0,0 +1,79 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C)
* Christopher Blizzard. All Rights Reserved.
*
* Contributor(s):
* Ed Burns <edburns@acm.org>
*/
#include "HttpHeaderVisitorImpl.h"
#include <nsAString.h>
#include <nsPromiseFlatString.h>
#include "ns_globals.h" // for prLogModuleInfo
#include "jni_util.h"
NS_IMPL_ISUPPORTS1(HttpHeaderVisitorImpl, nsIHttpHeaderVisitor)
HttpHeaderVisitorImpl::HttpHeaderVisitorImpl(JNIEnv * yourEnv,
jobject yourProperties,
jobject yourInitContext) :
mJNIEnv(yourEnv),
mInitContext(yourInitContext)
{
// create the inner properties object, into which we'll store our
// headers
mProperties = ::util_NewGlobalRef(mJNIEnv,
::util_CreatePropertiesObject(mJNIEnv, mInitContext));
// store it under the key "headers" in the outer properties object
::util_StoreIntoPropertiesObject(mJNIEnv, yourProperties, HEADERS_VALUE,
mProperties, mInitContext);
}
HttpHeaderVisitorImpl::~HttpHeaderVisitorImpl()
{
mJNIEnv = nsnull;
mProperties = nsnull;
mInitContext = nsnull;
}
NS_IMETHODIMP
HttpHeaderVisitorImpl::VisitHeader(const nsACString &header,
const nsACString &value)
{
jstring
headerName = (jstring)
::util_NewGlobalRef(mJNIEnv,
::util_NewStringUTF(mJNIEnv,
PromiseFlatCString(header).get())),
headerValue = (jstring)
::util_NewGlobalRef(mJNIEnv,
::util_NewStringUTF(mJNIEnv,
PromiseFlatCString(value).get()));
::util_StoreIntoPropertiesObject(mJNIEnv, mProperties, headerName,
headerValue, mInitContext);
PR_LOG(prLogModuleInfo, PR_LOG_DEBUG,
("HttpHeaderVisitorImpl::VisitHeader: name: %s value: %s\n",
PromiseFlatCString(header).get(),
PromiseFlatCString(value).get()));
// ::util_DeleteLocalRef(mJNIEnv, headerName);
// ::util_DeleteLocalRef(mJNIEnv, headerValue);
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,40 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C)
* Christopher Blizzard. All Rights Reserved.
*
* Contributor(s):
* Ed Burns <edburns@acm.org>
*/
#include "nsIHttpHeaderVisitor.h"
#include "jni.h"
class HttpHeaderVisitorImpl : public nsIHttpHeaderVisitor
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIHTTPHEADERVISITOR
HttpHeaderVisitorImpl(JNIEnv *myEnv, jobject myProperties,
jobject myInitContext);
virtual ~HttpHeaderVisitorImpl();
private:
JNIEnv *mJNIEnv;
jobject mProperties;
jobject mInitContext;
};

Просмотреть файл

@ -105,6 +105,8 @@ CPPSRCS = \
NativeWrapperFactory.cpp \
EmbedWindow.cpp \
EmbedProgress.cpp \
EventRegistrationImpl.cpp \
HttpHeaderVisitorImpl.cpp \
NativeEventThread.cpp \
NavigationImpl.cpp \
ns_util.cpp \

Просмотреть файл

@ -61,13 +61,15 @@ NativeBrowserControl::~NativeBrowserControl()
}
nsresult
NativeBrowserControl::Init()
NativeBrowserControl::Init(NativeWrapperFactory *yourWrapperFactory)
{
if (!util_StringConstantsAreInitialized()) {
util_InitStringConstants();
}
wrapperFactory = yourWrapperFactory;
// Create our embed window, and create an owning reference to it and
// initialize it. It is assumed that this window will be destroyed
// when we go out of scope.
@ -234,6 +236,11 @@ NativeBrowserControl::Destroy(void)
parentHWnd = nsnull;
}
NativeWrapperFactory *NativeBrowserControl::GetWrapperFactory()
{
return wrapperFactory;
}
jobject NativeBrowserControl::QueryInterfaceJava(WEBCLIENT_INTERFACES interface)
{
PR_ASSERT(nsnull != mJavaBrowserControl);

Просмотреть файл

@ -42,6 +42,7 @@
class EmbedProgress;
class EmbedWindow;
class NativeWrapperFactory;
/**
* <p>Native analog to BrowserControl. Hosts per-window things. Maps
@ -60,7 +61,7 @@ public:
// public API
//
nsresult Init ();
nsresult Init (NativeWrapperFactory *yourWrapperFactory);
nsresult Realize (jobject javaBrowserControl,
void* parentWinPtr,
PRBool *aAlreadyRealized,
@ -72,6 +73,8 @@ public:
PRUint32 aWidth, PRUint32 aHeight);
void Destroy (void);
NativeWrapperFactory * GetWrapperFactory();
jobject QueryInterfaceJava(WEBCLIENT_INTERFACES interface);
@ -105,6 +108,8 @@ public:
jobject mJavaBrowserControl;
NativeWrapperFactory * wrapperFactory;
};
#endif // NativeBrowserControl_h

Просмотреть файл

@ -350,7 +350,7 @@ JNIEXPORT void JNICALL Java_org_mozilla_webclient_impl_wrapper_1native_WrapperFa
"NULL nativeBCPtr passed to nativeInitBrowserControl.");
return;
}
rv = nativeBrowserControl->Init();
rv = nativeBrowserControl->Init(nativeWrapperFactory);
if (NS_FAILED(rv)) {
::util_ThrowExceptionToJava(env,
errorMessages[3]);

Просмотреть файл

@ -71,6 +71,9 @@ jobject TRUE_VALUE;
jobject FALSE_VALUE;
jobject ONE_VALUE;
jobject TWO_VALUE;
jobject URI_VALUE;
jobject HEADERS_VALUE;
jobject MESSAGE_VALUE;
jobject BM_ADD_DATE_VALUE;
jobject BM_LAST_MODIFIED_DATE_VALUE;
jobject BM_LAST_VISIT_DATE_VALUE;
@ -236,6 +239,21 @@ jboolean util_InitStringConstants()
::util_NewStringUTF(env, "2")))) {
return JNI_FALSE;
}
if (nsnull == (URI_VALUE =
::util_NewGlobalRef(env, (jobject)
::util_NewStringUTF(env, "URI")))) {
return JNI_FALSE;
}
if (nsnull == (HEADERS_VALUE =
::util_NewGlobalRef(env, (jobject)
::util_NewStringUTF(env, "headers")))) {
return JNI_FALSE;
}
if (nsnull == (MESSAGE_VALUE =
::util_NewGlobalRef(env, (jobject)
::util_NewStringUTF(env, "message")))) {
return JNI_FALSE;
}
if (nsnull == (BM_ADD_DATE_VALUE =
::util_NewGlobalRef(env, (jobject)
::util_NewStringUTF(env,

Просмотреть файл

@ -86,6 +86,9 @@ extern jobject TRUE_VALUE;
extern jobject FALSE_VALUE;
extern jobject ONE_VALUE;
extern jobject TWO_VALUE;
extern jobject URI_VALUE;
extern jobject HEADERS_VALUE;
extern jobject MESSAGE_VALUE;
extern jobject BM_ADD_DATE_VALUE;
extern jobject BM_LAST_MODIFIED_DATE_VALUE;
extern jobject BM_LAST_VISIT_DATE_VALUE;

Просмотреть файл

@ -1,5 +1,5 @@
/*
* $Id: CurrentPageTest.java,v 1.1 2004-09-03 19:04:22 edburns%acm.org Exp $
* $Id: DocumentLoadListenerTest.java,v 1.1 2004-09-09 20:17:17 edburns%acm.org Exp $
*/
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
@ -38,11 +38,11 @@ import java.awt.BorderLayout;
import java.io.File;
import java.io.FileInputStream;
// CurrentPageTest.java
// DocumentLoadListenerTest.java
public class CurrentPageTest extends WebclientTestCase {
public class DocumentLoadListenerTest extends WebclientTestCase {
public CurrentPageTest(String name) {
public DocumentLoadListenerTest(String name) {
super(name);
try {
BrowserControlFactory.setAppData(getBrowserBinDir());
@ -54,7 +54,7 @@ public class CurrentPageTest extends WebclientTestCase {
public static Test suite() {
TestSuite result = createServerTestSuite();
result.addTestSuite(CurrentPageTest.class);
result.addTestSuite(DocumentLoadListenerTest.class);
return (result);
}
@ -70,73 +70,9 @@ public class CurrentPageTest extends WebclientTestCase {
// Testcases
//
public void testHeadersGet() throws Exception {
public void testDocumentLoadListener() throws Exception {
BrowserControl firstBrowserControl = null;
DocumentLoadListenerImpl listener = null;
firstBrowserControl = BrowserControlFactory.newBrowserControl();
assertNotNull(firstBrowserControl);
BrowserControlCanvas canvas = (BrowserControlCanvas)
firstBrowserControl.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
eventRegistration = (EventRegistration2)
firstBrowserControl.queryInterface(BrowserControl.EVENT_REGISTRATION_NAME);
assertNotNull(canvas);
Frame frame = new Frame();
frame.setUndecorated(true);
frame.setBounds(0, 0, 640, 480);
frame.add(canvas, BorderLayout.CENTER);
frame.setVisible(true);
canvas.setVisible(true);
Navigation2 nav = (Navigation2)
firstBrowserControl.queryInterface(BrowserControl.NAVIGATION_NAME);
assertNotNull(nav);
final CurrentPage2 currentPage = (CurrentPage2)
firstBrowserControl.queryInterface(BrowserControl.CURRENT_PAGE_NAME);
assertNotNull(currentPage);
//
// try loading a file over HTTP
//
CurrentPageTest.keepWaiting = true;
eventRegistration.addDocumentLoadListener(listener = new DocumentLoadListenerImpl() {
public void doEndCheck() {
try {
Map responseHeaders = currentPage.getResponseHeaders();
assertNotNull(responseHeaders);
String server = (String) responseHeaders.get("Server");
assertNotNull(server);
assertEquals("THTTPD", server);
}
finally {
CurrentPageTest.keepWaiting = false;
}
}
});
String url = "http://www.jdocs.com/jsp/2.0/api/index.html"; //"http://localhost:5243/HttpNavigationTest.txt";
Thread.currentThread().sleep(3000);
nav.loadURL(url);
// keep waiting until the previous load completes
while (CurrentPageTest.keepWaiting) {
Thread.currentThread().sleep(1000);
}
eventRegistration.removeDocumentLoadListener(listener);
frame.setVisible(false);
BrowserControlFactory.deleteBrowserControl(firstBrowserControl);
}
public void NOTtestHttpPost() throws Exception {
BrowserControl firstBrowserControl = null;
DocumentLoadListenerImpl listener = null;
DocumentLoadListener listener = null;
Selection selection = null;
firstBrowserControl = BrowserControlFactory.newBrowserControl();
assertNotNull(firstBrowserControl);
@ -156,37 +92,112 @@ public class CurrentPageTest extends WebclientTestCase {
Navigation2 nav = (Navigation2)
firstBrowserControl.queryInterface(BrowserControl.NAVIGATION_NAME);
assertNotNull(nav);
final CurrentPage2 currentPage = (CurrentPage2)
firstBrowserControl.queryInterface(BrowserControl.CURRENT_PAGE_NAME);
assertNotNull(currentPage);
//
// try loading a file over HTTP
//
CurrentPageTest.keepWaiting = true;
DocumentLoadListenerTest.keepWaiting = true;
final String url = "http://localhost:5243/HttpNavigationTest.txt";
eventRegistration.addDocumentLoadListener(listener = new DocumentLoadListenerImpl() {
public void doEndCheck() {
currentPage.selectAll();
Selection selection = currentPage.getSelection();
CurrentPageTest.keepWaiting = false;
assertTrue(-1 != selection.toString().indexOf("This file was downloaded over HTTP."));
System.out.println("Selection is: " +
selection.toString());
eventRegistration.addDocumentLoadListener(listener = new DocumentLoadListener() {
public void eventDispatched(WebclientEvent event) {
if (event instanceof DocumentLoadEvent) {
switch ((int) event.getType()) {
case ((int) DocumentLoadEvent.END_URL_LOAD_EVENT_MASK):
assertNotNull(event.getEventData());
// PENDING(edburns): assertEquals(url, event.getEventData().toString());
assertTrue(event.getEventData() instanceof Map);
Map map = (Map) event.getEventData();
assertNull(map.get("headers"));
assertEquals(url, map.get("URI"));
break;
}
}
DocumentLoadListenerTest.keepWaiting = false;
}
});
String url = "http://localhost:5243/HttpCurrentPageTest.txt";
Thread.currentThread().sleep(3000);
nav.loadURL(url);
// keep waiting until the previous load completes
while (DocumentLoadListenerTest.keepWaiting) {
Thread.currentThread().sleep(1000);
}
eventRegistration.removeDocumentLoadListener(listener);
frame.setVisible(false);
BrowserControlFactory.deleteBrowserControl(firstBrowserControl);
}
public void testPageInfoListener() throws Exception {
BrowserControl firstBrowserControl = null;
DocumentLoadListener listener = null;
Selection selection = null;
firstBrowserControl = BrowserControlFactory.newBrowserControl();
assertNotNull(firstBrowserControl);
BrowserControlCanvas canvas = (BrowserControlCanvas)
firstBrowserControl.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
eventRegistration = (EventRegistration2)
firstBrowserControl.queryInterface(BrowserControl.EVENT_REGISTRATION_NAME);
assertNotNull(canvas);
Frame frame = new Frame();
frame.setUndecorated(true);
frame.setBounds(0, 0, 640, 480);
frame.add(canvas, BorderLayout.CENTER);
frame.setVisible(true);
canvas.setVisible(true);
Navigation2 nav = (Navigation2)
firstBrowserControl.queryInterface(BrowserControl.NAVIGATION_NAME);
assertNotNull(nav);
//
// try loading a file over HTTP
//
DocumentLoadListenerTest.keepWaiting = true;
final String url = "http://localhost:5243/HttpNavigationTest.txt";
eventRegistration.addDocumentLoadListener(listener = new PageInfoListener() {
public void eventDispatched(WebclientEvent event) {
if (event instanceof DocumentLoadEvent) {
switch ((int) event.getType()) {
case ((int) DocumentLoadEvent.END_URL_LOAD_EVENT_MASK):
assertNotNull(event.getEventData());
assertTrue(event.getEventData() instanceof Map);
Map map = (Map) event.getEventData();
assertEquals(url, map.get("URI"));
assertNotNull(map.get("headers"));
assertTrue(map.get("headers") instanceof Map);
Iterator iter = (map = (Map) map.get("headers")).keySet().iterator();
boolean hadCorrectServerHeader = false;
while (iter.hasNext()) {
String curName = iter.next().toString();
if (curName.equals("Server")) {
hadCorrectServerHeader = true;
}
System.out.println("\t" + curName +
": " +
map.get(curName));
}
assertTrue(hadCorrectServerHeader);
break;
}
}
DocumentLoadListenerTest.keepWaiting = false;
}
});
Thread.currentThread().sleep(3000);
nav.post(url, null, "PostData\r\n", "X-WakaWaka: true\r\n\r\n");
nav.loadURL(url);
// keep waiting until the previous load completes
while (CurrentPageTest.keepWaiting) {
while (DocumentLoadListenerTest.keepWaiting) {
Thread.currentThread().sleep(1000);
}
eventRegistration.removeDocumentLoadListener(listener);

Просмотреть файл

@ -28,6 +28,8 @@ import javax.swing.SwingConstants;
import java.io.File;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Map;
import java.util.Iterator;
import org.mozilla.webclient.*;
@ -216,8 +218,9 @@ public class TestBrowser extends JPanel {
return;
}
eventRegistration.addDocumentLoadListener(new DocumentLoadListener() {
eventRegistration.addDocumentLoadListener(new PageInfoListener() {
public void eventDispatched(WebclientEvent event) {
Map map = (Map) event.getEventData();
if (event instanceof DocumentLoadEvent) {
switch ((int) event.getType()) {
case ((int) DocumentLoadEvent.START_DOCUMENT_LOAD_EVENT_MASK):
@ -229,11 +232,22 @@ public class TestBrowser extends JPanel {
updateStatusInfo("Loading completed.");
if (event.getEventData() != null) {
jAddressTextField.setText(event.getEventData().toString());
jAddressTextField.setText(map.get("URI").toString());
}
break;
case ((int) DocumentLoadEvent.END_URL_LOAD_EVENT_MASK):
if (map.get("headers") instanceof Map) {
Iterator iter = (map = (Map) map.get("headers")).keySet().iterator();
while (iter.hasNext()) {
String curName = iter.next().toString();
System.out.println("\t" + curName +
": " +
map.get(curName));
}
}
break;
case ((int) DocumentLoadEvent.PROGRESS_URL_LOAD_EVENT_MASK):
// updateStatusInfo("Loading in progress...");
updateStatusInfo(map.get("message").toString());
break;
case ((int) DocumentLoadEvent.FETCH_INTERRUPT_EVENT_MASK):
updateStatusInfo("Loading error.");