/* * Copyright (c) 2006 Stiftung Deutsches Elektronen-Synchroton, * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY. * * THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS. * WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE * IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR * CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. * NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. * DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. * THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION, * USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS * PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY * AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM */ package org.csstudio.platform.internal.simpledal.local; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.csstudio.platform.ExecutionService; import org.csstudio.platform.model.pvs.IProcessVariableAddress; /** * Represents a local channel. * * @author Sven Wende * * @version $Revision$ */ public final class LocalChannel { private ScheduledFuture _scheduledFuture; private AbstractDataGenerator _dataGenerator; /** * The current value. */ private Object _currentValue; private List<ILocalChannelListener> _listeners; public LocalChannel(IProcessVariableAddress pv) { assert pv != null; _currentValue = null; _listeners = new ArrayList<ILocalChannelListener>(); // find data generator using regular expressions boolean found = false; for (DataGeneratorInfos dgInfo : DataGeneratorInfos.values()) { if (!found) { Pattern p = dgInfo.getPattern(); Matcher m = p.matcher(pv.getProperty()); if (m.find()) { found = true; // we apply only the first data generator // that fits // get the options that are encoded in the name of the // process variable final String[] options = new String[m.groupCount()]; for (int i = 0; i < m.groupCount(); i++) { options[i] = m.group(i+1); } // create and init the generator _dataGenerator = dgInfo.getDataGeneratorFactory() .createGenerator(this, 1000, options); // init the current value _currentValue = _dataGenerator.generateNextValue(); schedule(); } } } } public Object getValue() { return _currentValue; } public void setValue(Object value) { _currentValue = value; fireValueChangeEvent(); } public void addListener(ILocalChannelListener listener) { if (!_listeners.contains(listener)) { _listeners.add(listener); schedule(); } } public void removeListener(ILocalChannelListener listener) { boolean removed = _listeners.remove(listener); if (removed) { schedule(); } } private void fireValueChangeEvent() { for (ILocalChannelListener listener : _listeners) { listener.valueChanged(_currentValue); } } private void schedule() { // we need a data generator if (_dataGenerator != null) { // if nobody listens, we do not need to generate any random data if (_listeners.size() == 0) { // we cancel all scheduled jobs if (_scheduledFuture != null) { _scheduledFuture.cancel(false); _scheduledFuture = null; } } else { // we schedule the job if necessary if (_scheduledFuture == null) { _scheduledFuture = ExecutionService.getInstance() .getScheduledExecutorService().scheduleAtFixedRate( _dataGenerator, 1000, _dataGenerator.getPeriod(), TimeUnit.MILLISECONDS); } } } } }