/*
* 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.mapinput;
import java.awt.*;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.onemind.awtbridge.BridgeContextSession;
import org.onemind.awtbridge.event.BridgeEventQueue;
import org.onemind.awtbridge.event.ThreadlessBridgeEventQueue;
import org.onemind.awtbridge.input.InputDelegate;
import org.onemind.awtbridge.input.InputException;
import org.onemind.awtbridge.peer.BridgePeer;
import org.onemind.commons.java.util.ObjectUtils;
import org.onemind.commons.java.xml.digest.SaxDigesterHandler;
import org.onemind.swingweb.SwingWebContext;
import org.onemind.swingweb.input.AbstractSwingWebInputContext;
import org.onemind.swingweb.input.SwingWebInputContext;
import org.xml.sax.Attributes;
import sun.awt.AWTAutoShutdown;
/**
* The map input context
* @author TiongHiang Lee (thlee@onemindsoft.org)
*
*/
public class MapInputContext extends AbstractSwingWebInputContext implements SwingWebInputContext
{
private static final String KEY_EVENT_QUEUE = "EVENT_QUEUE";
/** the logger * */
private static final Logger _logger = Logger.getLogger(MapInputContext.class.getName());
/** whether to use threadless queue **/
private boolean _threadlessQueue = false;
private EventQueue _sharedThreadedQueue = null;
/**
* Constructor
* @param context the think client context
*/
public MapInputContext(SwingWebContext context)
{
super(context);
}
/**
* {@inheritDoc}
* @deprecated TODO: remove this method
*/
private final void handleInput(BridgePeer peer, Object obj) throws InputException
{
peer.processInput(this, obj);
}
/**
* {@inheritDoc}
*/
public final EventQueue getEventQueue()
{
return getBridgeEventQueue();
}
protected final BridgeEventQueue getBridgeEventQueue()
{
BridgeContextSession session = getContext().getSession();
synchronized (session)
{
BridgeEventQueue queue = (BridgeEventQueue) getContext().getSession().getValue(KEY_EVENT_QUEUE);
if (queue == null)
{
queue = _threadlessQueue ? new ThreadlessBridgeEventQueue(getSharedThreadedQueue()) : new BridgeEventQueue();
session.putValue(KEY_EVENT_QUEUE, queue);
}
return queue;
}
}
private synchronized EventQueue getSharedThreadedQueue(){
if (_sharedThreadedQueue==null){
_sharedThreadedQueue = new EventQueue();
}
return _sharedThreadedQueue;
}
/**
* Install the input delegate to the peer
* @param peer the peer
*/
public void installInputPeerDelegate(BridgePeer peer)
{
Object obj = peer.getComponentObject();
InputDelegate delegate = resolveDelegate(obj.getClass());
if (delegate == null)
{
throw new RuntimeException("Cannot resolve input delegate for " + peer);
} else
{
if (_logger.isLoggable(Level.FINEST))
{
_logger.finest("Assigning delegate " + delegate + " to " + obj);
}
peer.setInputDelegate(delegate);
}
}
/**
* {@inheritDoc}
*/
public final void dispatchEvents()
{
getBridgeEventQueue().flushEvents();
}
/**
* {@inheritDoc}
*/
public void handleInput(Object comObject, Object input) throws InputException
{
BridgePeer peer = (BridgePeer) getContext().getPeer(comObject);
if (peer != null)
{
peer.processInput(this, input);
//handleInput(peer, input);
} else
{
_logger.warning("Component " + comObject + " has no peer");
//throw new IllegalStateException("Component " + comObject + " has no peer");
}
}
/**
* {@inheritDoc}
*/
public void handleInput(Window win, Object input) throws InputException
{
handleInput((Object) win, input);//call the generic handle input method
dispatchEvents();
}
/**
* {@inheritDoc}
*/
public String getElementName()
{
return "mapinput";
}
/**
* {@inheritDoc}
*/
public void handleInput(Object input) throws InputException
{
//TODO: refactor this
List consoleWindows = getContext().getComponentManager().getConsoleWindows();
for (int i = 0; i < consoleWindows.size(); i++)
{
Window w = (Window) consoleWindows.get(i);
handleInput(w, input);
}
List windows = getContext().getComponentManager().getWindows();
for (int i = 0; i < windows.size(); i++)
{
Window w = (Window) windows.get(i);
handleInput(w, input);
}
}
/**
* {@inheritDoc}
*/
public void getRuntimeInfo(BridgePeer peer, Map env)
{
env.put("mapinputdelegate", resolveDelegate(peer.getComponentObject().getClass()));
}
/**
* Set whether to use thread less event queue
* @param threadless
*/
public void setThreadlessQueue(boolean threadless)
{
_threadlessQueue = threadless;
}
/**
* {@inheritDoc}
*/
public void startDigest(SaxDigesterHandler handler, Attributes attrs)
{
_threadlessQueue = ObjectUtils.toBool(attrs.getValue("threadlessQueue"), false);
super.startDigest(handler, attrs);
}
/**
* Return whether the input context useless threadless queue
* @return true if use threadless queue
*/
public boolean useThreadlessQueue()
{
return _threadlessQueue;
}
public void destroy()
{
if (_sharedThreadedQueue!=null){
AWTEvent eventThreadStopper = new AWTEvent(AWTAutoShutdown.getInstance(), 0){};
_sharedThreadedQueue.postEvent(eventThreadStopper);
}
}
}