001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.protocol.ws.api;
018
019import org.apache.wicket.Application;
020import org.apache.wicket.Page;
021import org.apache.wicket.Session;
022import org.apache.wicket.event.Broadcast;
023import org.apache.wicket.protocol.ws.WebSocketSettings;
024import org.apache.wicket.protocol.ws.api.event.WebSocketPayload;
025import org.apache.wicket.request.IRequestCycle;
026import org.apache.wicket.request.IRequestHandler;
027import org.apache.wicket.request.resource.IResource;
028import org.apache.wicket.request.resource.ResourceReference;
029import org.apache.wicket.request.resource.SharedResourceReference;
030import org.apache.wicket.util.lang.Args;
031import org.apache.wicket.util.lang.Classes;
032
033/**
034 * An {@link org.apache.wicket.request.IRequestHandler} that broadcasts the payload to the
035 * page/resource
036 */
037public class WebSocketMessageBroadcastHandler implements IRequestHandler
038{
039        private final int pageId;
040        private final String resourceName;
041        private final WebSocketPayload<?> payload;
042
043        /**
044         * Constructor.
045         *
046         * @param pageId
047         *          The id of the page if {@link org.apache.wicket.protocol.ws.api.WebSocketBehavior}
048         *          or {@value org.apache.wicket.protocol.ws.api.AbstractWebSocketProcessor#NO_PAGE_ID} if using a resource
049         * @param resourceName
050         *          The name of the shared {@link org.apache.wicket.protocol.ws.api.WebSocketResource}
051         * @param payload
052         *          The payload to broadcast
053         */
054        WebSocketMessageBroadcastHandler(int pageId, String resourceName, WebSocketPayload<?> payload)
055        {
056                this.pageId = pageId;
057                this.resourceName = resourceName;
058                this.payload = Args.notNull(payload, "payload");
059        }
060
061        @Override
062        public void respond(IRequestCycle requestCycle)
063        {
064                final Application application = Application.get();
065
066                final Runnable action = new Runnable()
067                {
068                        @Override
069                        public void run()
070                        {
071                                if (pageId != AbstractWebSocketProcessor.NO_PAGE_ID)
072                                {
073                                        Page page = (Page) Session.get().getPageManager().getPage(pageId);
074                                        page.send(application, Broadcast.BREADTH, payload);
075                                }
076                                else
077                                {
078                                        ResourceReference reference = new SharedResourceReference(resourceName);
079                                        IResource resource = reference.getResource();
080                                        if (resource instanceof WebSocketResource)
081                                        {
082                                                WebSocketResource wsResource = (WebSocketResource) resource;
083                                                wsResource.onPayload(payload);
084                                        }
085                                        else
086                                        {
087                                                throw new IllegalStateException(
088                                                                String.format("Shared resource with name '%s' is not a %s but %s",
089                                                                                resourceName, WebSocketResource.class.getSimpleName(),
090                                                                                Classes.name(resource.getClass())));
091                                        }
092                                }
093                        }
094                };
095
096                WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(application);
097                webSocketSettings.getSendPayloadExecutor().run(action);
098        }
099}