/*
GNU GENERAL PUBLIC LICENSE
Copyright (C) 2006 The Lobo Project
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
verion 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Contact info: lobochief@users.sourceforge.net
*/
/*
* Created on Mar 5, 2005
*/
package org.lobobrowser.request;
import java.io.IOException;
import java.net.URL;
import org.eclipse.jdt.annotation.NonNull;
import org.lobobrowser.clientlet.Clientlet;
import org.lobobrowser.clientlet.ClientletAccess;
import org.lobobrowser.clientlet.ClientletContext;
import org.lobobrowser.clientlet.ClientletException;
import org.lobobrowser.clientlet.ClientletRequest;
import org.lobobrowser.clientlet.ClientletResponse;
import org.lobobrowser.clientlet.ComponentContent;
import org.lobobrowser.context.ClientletContextImpl;
import org.lobobrowser.context.ClientletFactory;
import org.lobobrowser.gui.FramePanel;
import org.lobobrowser.gui.WindowCallback;
import org.lobobrowser.security.LocalSecurityManager;
import org.lobobrowser.ua.NavigatorProgressEvent;
import org.lobobrowser.ua.ProgressType;
import org.lobobrowser.ua.RequestType;
import org.lobobrowser.ua.UserAgentContext;
import org.lobobrowser.util.EventDispatch;
import org.lobobrowser.util.Urls;
/**
* @author J. H. S.
*/
public class ClientletRequestHandler extends AbstractRequestHandler {
private final WindowCallback windowCallback;
private final FramePanel frame;
/**
* For progress events, but a null event is also fired when the content is
* set.
*/
public final EventDispatch evtProgress = new EventDispatch();
public ClientletRequestHandler(final ClientletRequest request, final WindowCallback clientletUI, final FramePanel frame,
final UserAgentContext uaContext) {
super(request, frame.getComponent(), uaContext);
this.windowCallback = clientletUI;
this.frame = frame;
}
/*
* (non-Javadoc)
*
* @see
* net.sourceforge.xamj.http.RequestHandler#handleException(java.lang.Exception)
*/
@Override
public boolean handleException(final ClientletResponse response, final Throwable exception, final RequestType requestType)
throws ClientletException {
if (this.windowCallback != null) {
this.windowCallback.handleError(this.frame, response, exception, requestType);
return true;
} else {
return false;
}
}
private volatile java.util.Properties windowProperties = null;
public java.util.Properties getContextWindowProperties() {
return this.windowProperties;
}
/*
* (non-Javadoc)
*
* @see
* net.sourceforge.xamj.http.RequestHandler#processResponse(org.xamjwg.dom
* .ClientletResponse)
*/
@Override
public void processResponse(final ClientletResponse response) throws ClientletException, IOException {
if (this.windowCallback != null) {
this.windowCallback.handleDocumentAccess(this.frame, response);
}
final Clientlet clientlet = ClientletFactory.getInstance().getClientlet(this.getRequest(), response);
if (clientlet == null) {
throw new ClientletException("Unable to find clientlet for response: " + response + ".");
}
this.frame.setProgressEvent(null);
final ClientletContext ctx = new ClientletContextImpl(this.frame, this.request, response) {
@Override
public void setResultingContent(final ComponentContent content) {
// Frame content should be replaced as
// soon as this method is called to allow
// for incremental rendering.
super.setResultingContent(content);
windowProperties = this.getOverriddingWindowProperties();
// Replace content before firing progress
// event to avoid window flickering.
frame.replaceContent(response, content);
evtProgress.fireEvent(null);
}
};
final ClientletContext prevCtx = ClientletAccess.getCurrentClientletContext();
ClientletAccess.setCurrentClientletContext(ctx);
final ThreadGroup prevThreadGroup = LocalSecurityManager.getCurrentThreadGroup();
// TODO: Thread group needs to be thought through. It's retained in
// memory, and we need to return the right one in the GUI thread as well.
final ThreadGroup newThreadGroup = null; // new org.lobobrowser.context.ClientletThreadGroupImpl("CTG-" + ctx.getResponse().getResponseURL().getHost(), ctx);
LocalSecurityManager.setCurrentThreadGroup(newThreadGroup);
// Set context class loader because the extension was likely
// compiled to require extension libraries.
final Thread currentThread = Thread.currentThread();
final ClassLoader prevClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(clientlet.getClass().getClassLoader());
try {
clientlet.process(ctx);
} finally {
currentThread.setContextClassLoader(prevClassLoader);
LocalSecurityManager.setCurrentThreadGroup(prevThreadGroup);
ClientletAccess.setCurrentClientletContext(prevCtx);
}
this.frame.informResponseProcessed(response);
}
@Override
public void handleProgress(final ProgressType progressType, final @NonNull URL url, final String method, final int value, final int max) {
final NavigatorProgressEvent event = new NavigatorProgressEvent(this, this.frame, progressType, url, method, value, max);
this.evtProgress.fireEvent(event);
this.frame.setProgressEvent(event);
}
public static String getProgressMessage(final ProgressType progressType, final @NonNull URL url) {
final String urlText = Urls.getNoRefForm(url);
switch (progressType) {
case CONNECTING:
final String host = url.getHost();
if ((host == null) || "".equals(host)) {
return "Opening " + urlText;
} else {
return "Contacting " + host;
}
case SENDING:
return "Sending data to " + urlText;
case WAITING_FOR_RESPONSE:
return "Waiting on " + urlText;
case CONTENT_LOADING:
return "Loading " + urlText;
case BUILDING:
return "Building " + urlText;
case DONE:
return "Processed " + urlText;
default:
return "[?]" + urlText;
}
}
}