001/*
002 * GWTEventService
003 * Copyright (c) 2011 and beyond, strawbill UG (haftungsbeschr?nkt)
004 *
005 * This is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU Lesser General Public License as
007 * published by the Free Software Foundation; either version 3 of
008 * the License, or (at your option) any later version.
009 * Other licensing for GWTEventService may also be possible on request.
010 * Please view the license.txt of the project for more information.
011 *
012 * This software is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this software; if not, write to the Free
019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021 */
022package de.novanic.eventservice.service.connection.strategy.connector;
023
024import de.novanic.eventservice.config.EventServiceConfiguration;
025import de.novanic.eventservice.service.EventServiceException;
026import de.novanic.eventservice.service.registry.user.UserInfo;
027
028import java.io.UnsupportedEncodingException;
029
030/**
031 * {@link ConnectionStrategyServerConnectorAdapter} is an abstract default implementation of {@link ConnectionStrategyServerConnector}
032 * and offers some general methods for the internal operation which can be useful for various connection strategies.
033 * The {@link ConnectionStrategyServerConnector} listens for occurring events ({@link de.novanic.eventservice.client.event.Event})
034 * on the server side and has the task to prepare the transfer from the server side to the client side.
035 *
036 * The reason for the listen and transfer preparation within one single class is, that the {@link ConnectionStrategyServerConnector}
037 * should have the control about listening and transfer of the occurred events.
038 *
039 * @author sstrohschein
040 *         <br>Date: 15.03.2010
041 *         <br>Time: 23:03:02
042 */
043public abstract class ConnectionStrategyServerConnectorAdapter implements ConnectionStrategyServerConnector
044{
045    private EventServiceConfiguration myConfiguration;
046    private static String ENCODING;
047
048    /**
049     * Creates a new connection strategy with a configuration ({@link de.novanic.eventservice.config.EventServiceConfiguration}).
050     * @param aConfiguration configuration
051     */
052    protected ConnectionStrategyServerConnectorAdapter(EventServiceConfiguration aConfiguration) {
053        myConfiguration = aConfiguration;
054        ENCODING = myConfiguration.getConnectionStrategyEncoding();
055    }
056
057    /**
058     * Returns the configuration which was provided to this connector adapter.
059     * @return configuration
060     */
061    protected EventServiceConfiguration getConfiguration() {
062        return myConfiguration;
063    }
064
065    /**
066     * Waits for the configured min. waiting time.
067     * @see de.novanic.eventservice.config.ConfigParameter#MIN_WAITING_TIME_TAG
068     * @throws EventServiceException
069     */
070    protected void waitMinWaitingTime() throws EventServiceException {
071        waitTime(myConfiguration.getMinWaitingTime());
072    }
073
074    /**
075     * Waits for the configured max. waiting time and returns whether the max. waiting time
076     * was exceed or was interrupted by an occurred event (notification).
077     * @param aUserInfo user
078     * @return true when the max. waiting time was exceed, otherwise (interrupted by a notification) false
079     * @throws EventServiceException can occur when the waiting was interrupted by an error
080     */
081    protected boolean waitMaxWaitingTime(UserInfo aUserInfo) throws EventServiceException {
082        final int theMaxWaitingTime = myConfiguration.getMaxWaitingTime();
083        if(theMaxWaitingTime <= 0) {
084            return true;
085        }
086        if(aUserInfo.isEventsEmpty()) {
087            //monitor for event notification and double checked
088            synchronized(aUserInfo) {
089                if(aUserInfo.isEventsEmpty()) {
090                    try {
091                        final long theStartTime = System.currentTimeMillis();
092                        aUserInfo.wait(theMaxWaitingTime);
093                        return (System.currentTimeMillis() - theStartTime >= theMaxWaitingTime);
094                    } catch(InterruptedException e) {
095                        throw new EventServiceException("Error on waiting max. waiting time!", e);
096                    }
097                }
098            }
099        }
100        return false;
101    }
102
103    /**
104     * Waits for a specified time.
105     * @param aWaitingTime time to wait
106     * @throws EventServiceException
107     */
108    private void waitTime(int aWaitingTime) throws EventServiceException {
109        if(aWaitingTime > 0) {
110            try {
111                Thread.sleep(aWaitingTime);
112            } catch(InterruptedException e) {
113                throw new EventServiceException("Error on waiting min. waiting time!", e);
114            }
115        }
116    }
117
118    /**
119     * Returns the configured encoding.
120     * @return configured encoding
121     * @throws EventServiceException
122     */
123    protected static String getEncoding() throws EventServiceException {
124        if(ENCODING != null) {
125            return ENCODING;
126        }
127        throw new EventServiceException("The encoding property wasn't initialized. It is initialized with the configuration at the time of object construction.");
128    }
129
130    /**
131     * Encodes an string with the configured encoding.
132     * @param aString String to encode
133     * @return encoded string
134     * @throws EventServiceException
135     */
136    protected static byte[] encode(String aString) throws EventServiceException {
137        try {
138            return aString.getBytes(getEncoding());
139        } catch(UnsupportedEncodingException e) {
140            throw new EventServiceException("Error on encoding \"" + aString + "\"!", e); //shouldn't be able to occur
141        }
142    }
143}