/*
* Copyright (C) 2004 TiongHiang Lee
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Email: thlee@onemindsoft.org
*/
package org.onemind.swingweb.client.gwt;
import java.util.*;
import org.onemind.swingweb.client.core.AbstractClient;
import org.onemind.swingweb.client.core.ui.UIHandler;
import org.onemind.swingweb.client.dom.*;
import org.onemind.swingweb.client.domimpl.Document;
import org.onemind.swingweb.client.gwt.ui.DefaultGWTUIHandler;
import com.google.gwt.user.client.*;
import com.google.gwt.user.client.ui.*;
public class GwtClient extends AbstractClient implements ResponseTextHandler, FormHandler
{
private UIHandler _defaultHandler = new DefaultGWTUIHandler(this);
private int _requestId = 0;
private GwtClientConsole _console;
private boolean _useJavaNameForStyle = true;
private Set _windows = new HashSet();
private long _submitStart;
private String currentSessionId;
private static class MessageDialog extends DialogBox
{
public MessageDialog(String caption, String message)
{
// Set the dialog box's caption.
setText(caption);
// DialogBox is a SimplePanel, so you have to set it's widget property to
// whatever you want its contents to be.
Button ok = new Button("OK");
ok.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
MessageDialog.this.hide();
}
});
VerticalPanel panel = new VerticalPanel();
panel.add(new Label(message));
panel.add(ok);
setWidget(panel);
}
}
public GwtClient(String url)
{
super(url);
setLogLevel(LOG_TERSE, true);
_console = new GwtClientConsole(this);
log(LOG_TERSE, "Client start on url " + url);
refreshUI();
}
public void log(String logLevel, String msg)
{
if (_console != null)
{
if (isLoggable(logLevel))
{
_console.appendMessage(msg);
}
}
}
public synchronized void onCompletion(String responseText)
{
log(LOG_TERSE, "Received response");
log(LOG_DEBUG, "Response text = " + responseText);
log(LOG_TERSE, "Request time = " + (System.currentTimeMillis() - _submitStart) + "ms");
_submitStart = System.currentTimeMillis();
log(LOG_VERBOSE, "Window list size = " + _windows.size());
if (responseText.trim().length() > 0)
{
if (responseText.indexOf("<error") == -1)
{ //no error
_console.setStatus(GwtClientConsole.STATUS_RENDER);
DomDocument doc = Document.xmlParse(responseText);
List children = doc.getChildren();
if (children.size() > 0)
{
DomNode first = (DomNode) children.get(0);
if (first.getName().equalsIgnoreCase("thin-ui"))
{
String sessionId = first.getAttribute("sessionId");
if (currentSessionId == null)
{
currentSessionId = sessionId;
log(LOG_TERSE, "Session " + sessionId + " started");
} else
{
if (!currentSessionId.equals(sessionId))
{
log(LOG_TERSE, "Previous session has expired. Session purged");
purgeSession();
currentSessionId = sessionId;
log(LOG_TERSE, "Session " + sessionId + " started");
}
}
children = DomHelper.getChildrenByTag(first, "element");
Set windows = new HashSet();
int x = 50, y = 150;
for (int i = 0; i < children.size(); i++)
{
DomNode n = (DomNode) children.get(i);
Widget o = (Widget) handle(null, n);
if (o != null)
{
if (!o.isAttached())
{
RootPanel.get().add(o, x, y);
}
x = o.getAbsoluteLeft() + 100;
y = o.getAbsoluteTop() + 100;
log(LOG_DEBUG, "Adding window " + n.getAttribute("id"));
windows.add(o);
}
}
_windows.removeAll(windows);
Iterator it = _windows.iterator();
while (it.hasNext())
{
Widget w = (Widget) it.next();
log(LOG_DEBUG, "Remove window " + w);
w.removeFromParent();
}
log(LOG_TERSE, "Rendering time = " + (System.currentTimeMillis() - _submitStart) + "ms");
log(LOG_TERSE, "Done");
_windows = windows;
getChanges().clear();
_console.setStatus(GwtClientConsole.STATUS_SYNC);
} else
{
throw new IllegalArgumentException("The result is not a thin-ui protocol");
}
}
} else
{
MessageDialog dlg = new MessageDialog("Error", "There are some problem processing the request");
dlg.show();
_console.setStatus(GwtClientConsole.STATUS_SYNC);
}
}
}
private String buildQueryString(Map changes)
{
StringBuffer sb = new StringBuffer();
boolean first = true;
for (Iterator it = changes.entrySet().iterator(); it.hasNext();)
{
Map.Entry queryEntry = (Map.Entry) it.next();
if (!first)
{
sb.append("&");
} else
{
first = false;
}
// encode the characters in the name
//String encodedName = URL.encodeComponent((String) queryEntry.getKey());
String encodedName = (String) queryEntry.getKey();
sb.append(encodedName);
sb.append("=");
// encode the characters in the value
//String encodedValue = URL.encodeComponent((String) queryEntry.getValue());
if (queryEntry.getValue() instanceof String)
{
String encodedValue = (String) queryEntry.getValue();
sb.append(encodedValue);
} else
{
String[] encodedValue = (String[]) queryEntry.getValue();
for (int i = 0; i < encodedValue.length; i++)
{
sb.append(encodedValue[i]);
if (i < encodedValue.length - 1)
{
sb.append("&");
sb.append(encodedName);
sb.append("=");
}
}
}
}
return sb.toString();
}
public void submitRequest()
{
try
{
String request = getUrl() + "?" + buildQueryString(getChanges());
HTTPRequest.asyncGet(request, this);
_requestId++;
_submitStart = System.currentTimeMillis();
_console.setStatus(GwtClientConsole.STATUS_REQUEST);
} catch (Exception e)
{
log(LOG_TERSE, "Error: " + e.getMessage());
e.printStackTrace();
}
}
public void submitRequest(FormPanel form)
{
try
{
form.setAction(getUrl());
form.addFormHandler(this);
_submitStart = System.currentTimeMillis();
form.submit();
log(LOG_TERSE, "Form submitted in " + (_submitStart - System.currentTimeMillis()) + "ms");
_submitStart = System.currentTimeMillis();
_console.setStatus(GwtClientConsole.STATUS_REQUEST);
} catch (Exception e)
{
log(LOG_TERSE, "Error: " + e.getMessage());
e.printStackTrace();
}
}
public void refreshUI()
{
log(LOG_TERSE, "RefreshUI. Sending request to " + getUrl());
submitRequest();
}
public GwtClientConsole getConsole()
{
return _console;
}
public Object handle(Object parent, DomNode element, String id)
{
String className = element.getAttribute("class");
String handlerName = element.getAttribute("handler");
UIHandler handler = (UIHandler) getHandlerByName(handlerName);
if (handler == null)
{
handler = _defaultHandler;
log(LOG_TERSE, "Unable to handle " + className);
}
Object com = null;
try
{
if (id != null)
{
if (getComponent(id) != null)
{
com = handler.updateComponent(getComponent(id), element);
} else
{
com = handler.createComponent(parent, element);
addComponent(id, com);
}
} else
{//for table cells
com = handler.createComponent(parent, element);
}
return com;
} catch (Exception e)
{
e.printStackTrace();
log(LOG_TERSE, "Cannot handle " + id + " Exception " + e);
return new Label(e.getMessage());
}
}
/**
* Return the useJavaNameForStyle
* @return the useJavaNameForStyle.
*/
public final boolean isUseJavaNameForStyle()
{
return _useJavaNameForStyle;
}
/**
* Set the useJavaNameForStyle
* @param useJavaNameForStyle The useJavaNameForStyle to set.
*/
public final void setUseJavaNameForStyle(boolean useJavaNameForStyle)
{
_useJavaNameForStyle = useJavaNameForStyle;
}
/**
* {@inheritDoc}
*/
public void addComponent(String id, Object com)
{
DOM.setAttribute(((UIObject) com).getElement(), "id", id);
super.addComponent(id, com);
}
public void onSubmit(FormSubmitEvent event)
{
//do nothing
}
public void onSubmitComplete(FormSubmitCompleteEvent event)
{
log(LOG_TERSE, "form submit result = " + event.getResults());
refreshUI();
}
}