Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 1 addition & 86 deletions api/src/main/java/javax/faces/component/_UIWebsocket.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
defaultRendererType = "javax.faces.Websocket",
implementz = "javax.faces.component.behavior.ClientBehaviorHolder",
bodyContent = "empty")
abstract class _UIWebsocket extends UIOutput implements ClientBehaviorHolder
abstract class _UIWebsocket extends UIComponentBase
{

static public final String COMPONENT_FAMILY = "javax.faces.Script";
Expand All @@ -60,89 +60,4 @@ abstract class _UIWebsocket extends UIOutput implements ClientBehaviorHolder
@JSFProperty(defaultValue = "true")
public abstract boolean isConnected();

@Override
public java.util.Collection<String> getEventNames()
{
return new java.util.Collection<String>(){

@Override
public int size()
{
return 0;
}

@Override
public boolean isEmpty()
{
return false;
}

@Override
public boolean contains(Object o)
{
return true;
}

@Override
public java.util.Iterator<String> iterator()
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public Object[] toArray()
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public <T> T[] toArray(T[] a)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean add(String e)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean remove(Object o)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean containsAll(java.util.Collection<?> c)
{
return true;
}

@Override
public boolean addAll(java.util.Collection<? extends String> c)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean removeAll(java.util.Collection<?> c)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean retainAll(java.util.Collection<?> c)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void clear()
{
throw new UnsupportedOperationException("Not supported yet.");
}
};
}

}
93 changes: 93 additions & 0 deletions api/src/main/resources/META-INF/componentClass20.vm
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,99 @@ $innersource
}
#end
#end

#if ($component.implements)
#if ( ($component.implements == "javax.faces.component.behavior.ClientBehaviorHolder")
&& (${utils.getClassFromFullClass($component.className)} == "UIWebsocket"))
// Start UIWebsocket getEventNames template
@Override
public java.util.Collection<String> getEventNames()
{
return new java.util.Collection<String>(){

@Override
public int size()
{
return 0;
}

@Override
public boolean isEmpty()
{
return false;
}

@Override
public boolean contains(Object o)
{
return true;
}

@Override
public java.util.Iterator<String> iterator()
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public Object[] toArray()
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public <T> T[] toArray(T[] a)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean add(String e)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean remove(Object o)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean containsAll(java.util.Collection<?> c)
{
return true;
}

@Override
public boolean addAll(java.util.Collection<? extends String> c)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean removeAll(java.util.Collection<?> c)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public boolean retainAll(java.util.Collection<?> c)
{
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void clear()
{
throw new UnsupportedOperationException("Not supported yet.");
}
};
}
// End UIWebsocket getEventNames template
#end
#end

#if ($component.defaultEventName)
#if ($component.defaultEventName != "")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,79 +112,72 @@ public void encodeEnd(FacesContext facesContext, UIComponent c) throws IOExcepti

ResponseWriter writer = facesContext.getResponseWriter();

//Only the first time it is required a session id.
if (component.getValue() == null)
String channel = component.getChannel();

// TODO: use a single bean and entry point for this algorithm.
BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());

WebsocketChannelTokenBuilderBean channelTokenBean = CDIUtils.lookup(
beanManager,
WebsocketChannelTokenBuilderBean.class);

// This bean is required because you always need to register the token, so it can be properly destroyed
WebsocketViewBean viewTokenBean = CDIUtils.lookup(
beanManager,
WebsocketViewBean.class);
WebsocketSessionBean sessionTokenBean = CDIUtils.lookup(
beanManager, WebsocketSessionBean.class);

// Create channel token
// TODO: Use ResponseStateManager to create the token
String scope = component.getScope() == null ? "application" : component.getScope();
WebsocketChannelMetadata metadata = new WebsocketChannelMetadata(
channel, scope, component.getUser(), component.isConnected());

String channelToken = null;
// Force a new channelToken if "connected" property is set to false, because in that case websocket
// creation
if (!component.isConnected())
{
String channel = component.getChannel();

// TODO: use a single bean and entry point for this algorithm.
BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());

WebsocketChannelTokenBuilderBean channelTokenBean = CDIUtils.lookup(
beanManager,
WebsocketChannelTokenBuilderBean.class);

// This bean is required because you always need to register the token, so it can be properly destroyed
WebsocketViewBean viewTokenBean = CDIUtils.lookup(
beanManager,
WebsocketViewBean.class);
WebsocketSessionBean sessionTokenBean = CDIUtils.lookup(
beanManager, WebsocketSessionBean.class);

// Create channel token
// TODO: Use ResponseStateManager to create the token
String scope = component.getScope() == null ? "application" : component.getScope();
WebsocketChannelMetadata metadata = new WebsocketChannelMetadata(
channel, scope, component.getUser(), component.isConnected());

String channelToken = null;
// Force a new channelToken if "connected" property is set to false, because in that case websocket
// creation
if (!component.isConnected())
{
channelToken = viewTokenBean.getChannelToken(metadata);
}
if (channelToken == null)
{
// No channel token found for that combination, create a new token for this view
channelToken = channelTokenBean.createChannelToken(facesContext, channel);

// Register the channel into the bean that will manage the Session instance used to do the push
component.setValue(channelToken);

// Register channel in view scope to chain discard view algorithm using @PreDestroy
viewTokenBean.registerToken(channelToken, metadata);

// Register channel in session scope to allow validation on handshake ( WebsocketConfigurator )
sessionTokenBean.registerToken(channelToken, metadata);
}
channelToken = viewTokenBean.getChannelToken(metadata);
}
if (channelToken == null)
{
// No channel token found for that combination, create a new token for this view
channelToken = channelTokenBean.createChannelToken(facesContext, channel);

// Register channel in view scope to chain discard view algorithm using @PreDestroy
viewTokenBean.registerToken(channelToken, metadata);

// Register channel in session scope to allow validation on handshake ( WebsocketConfigurator )
sessionTokenBean.registerToken(channelToken, metadata);
}

// Ask these two scopes
WebsocketApplicationBean appTokenBean = CDIUtils.getInstance(
beanManager, WebsocketApplicationBean.class, false);
// Ask these two scopes
WebsocketApplicationBean appTokenBean = CDIUtils.getInstance(
beanManager, WebsocketApplicationBean.class, false);

// Register token and metadata in the proper bean
if (scope.equals("view"))
{
viewTokenBean.registerWebsocketSession(channelToken, metadata);
}
else if (scope.equals("session"))
{
sessionTokenBean = (sessionTokenBean != null) ? sessionTokenBean : CDIUtils.lookup(
CDIUtils.getBeanManager(facesContext.getExternalContext()),
WebsocketSessionBean.class);
// Register token and metadata in the proper bean
if (scope.equals("view"))
{
viewTokenBean.registerWebsocketSession(channelToken, metadata);
}
else if (scope.equals("session"))
{
sessionTokenBean = (sessionTokenBean != null) ? sessionTokenBean : CDIUtils.lookup(
CDIUtils.getBeanManager(facesContext.getExternalContext()),
WebsocketSessionBean.class);

sessionTokenBean.registerWebsocketSession(channelToken, metadata);
}
else
{
//Default application
appTokenBean = (appTokenBean != null) ? appTokenBean : CDIUtils.lookup(
CDIUtils.getBeanManager(facesContext.getExternalContext()),
WebsocketApplicationBean.class);
sessionTokenBean.registerWebsocketSession(channelToken, metadata);
}
else
{
//Default application
appTokenBean = (appTokenBean != null) ? appTokenBean : CDIUtils.lookup(
CDIUtils.getBeanManager(facesContext.getExternalContext()),
WebsocketApplicationBean.class);

appTokenBean.registerWebsocketSession(channelToken, metadata);
}
appTokenBean.registerWebsocketSession(channelToken, metadata);
}

writer.startElement(HTML.SCRIPT_ELEM, component);
Expand All @@ -196,7 +189,7 @@ else if (scope.equals("session"))
sb.append(",");
sb.append("'"+facesContext.getExternalContext().encodeWebsocketURL(
facesContext.getApplication().getViewHandler().getWebsocketURL(
facesContext, component.getChannel()+"?"+(String) component.getValue()))+"'");
facesContext, component.getChannel()+"?"+channelToken))+"'");
sb.append(",");
sb.append("'"+component.getChannel()+"'");
sb.append(",");
Expand Down