001package jmri.jmrit.logixng.implementation;
002
003import java.util.*;
004
005import jmri.*;
006import jmri.jmrit.logixng.*;
007
008/**
009 * Default implementation of the clipboard
010 *
011 * @author Daniel Bergqvist (C) 2020
012 */
013public class DefaultClipboard extends AbstractBase implements Clipboard {
014
015    private ClipboardMany _clipboardItems = new ClipboardMany("", null);
016
017    private final FemaleAnySocket _femaleSocket = new DefaultFemaleAnySocket(this, new FemaleSocketListener() {
018        @Override
019        public void connected(FemaleSocket socket) {
020            // Do nothing
021        }
022
023        @Override
024        public void disconnected(FemaleSocket socket) {
025            // Do nothing
026        }
027    }, "A");
028
029
030    public DefaultClipboard() {
031        super("IQClipboard");
032
033        // Listeners should never be enabled for the clipboard
034        _femaleSocket.setEnableListeners(false);
035
036        try {
037            _femaleSocket.connect(new MaleRootSocket(new MaleRootManager()));
038        } catch (SocketAlreadyConnectedException ex) {
039            // This should never happen
040            throw new RuntimeException("Program error", ex);
041        }
042        if (!_femaleSocket.setParentForAllChildren(new ArrayList<>())) {
043            throw new RuntimeException("Failed to set parent for all children");
044        }
045        _clipboardItems.setParent(_femaleSocket.getConnectedSocket());
046    }
047
048    @Override
049    public boolean isEmpty() {
050        return _clipboardItems.getChildCount() == 0;
051    }
052
053    @Override
054    public boolean add(MaleSocket maleSocket, List<String> errors) {
055        _clipboardItems.ensureFreeSocketAtTop();
056        try {
057            _clipboardItems.getChild(0).connect(maleSocket);
058            return _clipboardItems.setParentForAllChildren(errors);
059        } catch (SocketAlreadyConnectedException ex) {
060            throw new RuntimeException("Cannot add socket", ex);
061        }
062    }
063
064    @Override
065    public MaleSocket fetchTopItem() {
066        if (!isEmpty()) {
067            MaleSocket maleSocket = _clipboardItems.getChild(0).getConnectedSocket();
068            _clipboardItems.getChild(0).disconnect();
069            return maleSocket;
070        } else {
071            return null;
072        }
073    }
074
075    @Override
076    public MaleSocket getTopItem() {
077        if (!isEmpty()) {
078            return _clipboardItems.getChild(0).getConnectedSocket();
079        } else {
080            return null;
081        }
082    }
083
084    @Override
085    public FemaleSocket getFemaleSocket() {
086        return _femaleSocket;
087    }
088
089    @Override
090    public void moveItemToTop(MaleSocket maleSocket) {
091        _clipboardItems.ensureFreeSocketAtTop();
092        if (maleSocket.getParent() != null) {
093            if (!(maleSocket.getParent() instanceof FemaleSocket)) {
094                throw new UnsupportedOperationException("maleSocket.parent() is not a female socket");
095            }
096            ((FemaleSocket)maleSocket.getParent()).disconnect();
097        }
098        try {
099            _clipboardItems.getChild(0).connect(maleSocket);
100        } catch (SocketAlreadyConnectedException ex) {
101            throw new UnsupportedOperationException("Cannot move item to clipboard", ex);
102        }
103    }
104
105    @Override
106    public void setup() {
107        _clipboardItems.setup();
108    }
109
110    public boolean replaceClipboardItems(ClipboardMany clipboardItems, List<String> errors) {
111        _clipboardItems = clipboardItems;
112
113        _femaleSocket.disconnect();
114
115        try {
116            _femaleSocket.connect(new MaleRootSocket(new MaleRootManager()));
117        } catch (SocketAlreadyConnectedException ex) {
118            // This should never happen
119            throw new RuntimeException("Program error", ex);
120        }
121        boolean result = _femaleSocket.setParentForAllChildren(errors);
122        _clipboardItems.setParent(_femaleSocket.getConnectedSocket());
123        return result;
124    }
125
126    @Override
127    protected void registerListenersForThisClass() {
128        throw new UnsupportedOperationException("Not supported");
129    }
130
131    @Override
132    protected void unregisterListenersForThisClass() {
133        throw new UnsupportedOperationException("Not supported");
134    }
135
136    @Override
137    protected void disposeMe() {
138        throw new UnsupportedOperationException("Not supported");
139    }
140
141    @Override
142    public void setState(int s) throws JmriException {
143        throw new UnsupportedOperationException("Not supported");
144    }
145
146    @Override
147    public int getState() {
148        throw new UnsupportedOperationException("Not supported");
149    }
150
151    @Override
152    public String getBeanType() {
153        throw new UnsupportedOperationException("Not supported");
154    }
155
156    @Override
157    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException {
158        throw new UnsupportedOperationException("Not supported");
159    }
160
161    @Override
162    public String getShortDescription(Locale locale) {
163        throw new UnsupportedOperationException("Not supported");
164    }
165
166    @Override
167    public String getLongDescription(Locale locale) {
168        throw new UnsupportedOperationException("Not supported");
169    }
170
171    @Override
172    public Base getParent() {
173        return null;
174    }
175
176    @Override
177    public void setParent(Base parent) {
178        throw new UnsupportedOperationException("Not supported");
179    }
180
181    @Override
182    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
183        return _clipboardItems.getChild(index);
184    }
185
186    @Override
187    public int getChildCount() {
188        return _clipboardItems.getChildCount();
189    }
190
191    @Override
192    public LogixNG_Category getCategory() {
193        throw new UnsupportedOperationException("Not supported");
194    }
195
196
197    private interface ClipboardManySocket extends NamedBean, MaleSocket {
198    }
199
200
201    private class MaleRootSocket extends AbstractMaleSocket implements ClipboardManySocket {
202
203        public MaleRootSocket(BaseManager<? extends NamedBean> manager) {
204            super(manager, _clipboardItems);
205        }
206
207        @Override
208        protected void registerListenersForThisClass() {
209            throw new UnsupportedOperationException("Not supported");
210        }
211
212        @Override
213        protected void unregisterListenersForThisClass() {
214            throw new UnsupportedOperationException("Not supported");
215        }
216
217        @Override
218        protected void disposeMe() {
219            _clipboardItems.dispose();
220        }
221
222        @Override
223        public void setEnabled(boolean enable) {
224            throw new UnsupportedOperationException("Not supported");
225        }
226
227        @Override
228        public void setEnabledFlag(boolean enable) {
229            throw new UnsupportedOperationException("Not supported");
230        }
231
232        @Override
233        public boolean isEnabled() {
234            return _clipboardItems.isEnabled();
235        }
236
237        @Override
238        public void setDebugConfig(DebugConfig config) {
239            throw new UnsupportedOperationException("Not supported");
240        }
241
242        @Override
243        public DebugConfig getDebugConfig() {
244            return null;
245        }
246
247        @Override
248        public DebugConfig createDebugConfig() {
249            throw new UnsupportedOperationException("Not supported");
250        }
251
252        @Override
253        public String getComment() {
254            return _clipboardItems.getComment();
255        }
256
257        @Override
258        public void setComment(String s) throws NamedBean.BadUserNameException {
259            throw new UnsupportedOperationException("Not supported");
260        }
261
262        @Override
263        public void setState(int s) throws JmriException {
264            throw new UnsupportedOperationException("Not supported");
265        }
266
267        @Override
268        public int getState() {
269            throw new UnsupportedOperationException("Not supported");
270        }
271
272        @Override
273        public String describeState(int state) {
274            throw new UnsupportedOperationException("Not supported");
275        }
276
277        @Override
278        public void setProperty(String key, Object value) {
279            throw new UnsupportedOperationException("Not supported");
280        }
281
282        @Override
283        public Object getProperty(String key) {
284            throw new UnsupportedOperationException("Not supported");
285        }
286
287        @Override
288        public void removeProperty(String key) {
289            throw new UnsupportedOperationException("Not supported");
290        }
291
292        @Override
293        public Set<String> getPropertyKeys() {
294            throw new UnsupportedOperationException("Not supported");
295        }
296
297        @Override
298        public String getBeanType() {
299            throw new UnsupportedOperationException("Not supported");
300        }
301
302        @Override
303        public int compareSystemNameSuffix(String suffix1, String suffix2, NamedBean n2) {
304            throw new UnsupportedOperationException("Not supported");
305        }
306
307    }
308
309
310    private static class MaleRootManager extends AbstractBaseManager<ClipboardManySocket> {
311
312        @Override
313        protected ClipboardManySocket castBean(MaleSocket maleSocket) {
314            throw new UnsupportedOperationException("Not supported");
315        }
316
317        @Override
318        public char typeLetter() {
319            throw new UnsupportedOperationException("Not supported");
320        }
321
322        @Override
323        public Class<ClipboardManySocket> getNamedBeanClass() {
324            return ClipboardManySocket.class;
325        }
326
327        @Override
328        public int getXMLOrder() {
329            return Integer.MAX_VALUE;
330        }
331
332        @Override
333        public String getBeanTypeHandled(boolean plural) {
334            throw new UnsupportedOperationException("Not supported");
335        }
336
337        @Override
338        public Class<ClipboardManySocket> getMaleSocketClass() {
339            throw new UnsupportedOperationException("Not supported");
340        }
341
342        @Override
343        public MaleSocket getLastRegisteredMaleSocket() {
344            throw new UnsupportedOperationException("Not supported");
345        }
346
347    }
348
349}