001package jmri.jmrit.logix; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.beans.PropertyChangeSupport; 006 007import java.util.*; 008 009import javax.annotation.Nonnull; 010import javax.annotation.OverridingMethodsMustInvokeSuper; 011 012/** 013 * Basic implementation of a PortalManager. 014 * <p> 015 * Note that this does not enforce any particular system naming convention. 016 * <p> 017 * Note this is an 'after thought' manager. Portals have been in use since 2009. 018 * Their use has now expanded well beyond what was expected. A Portal factory is 019 * needed for development to continue. 020 * 021 * Portal system names will be numbers and they will not be shown to users. The 022 * UI will treat Portal names as it does now as user names. 023 * 024 * <hr> 025 * This file is part of JMRI. 026 * <p> 027 * JMRI is free software; you can redistribute it and/or modify it under the 028 * terms of version 2 of the GNU General Public License as published by the Free 029 * Software Foundation. See the "COPYING" file for a copy of this license. 030 * <p> 031 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 032 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 033 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 034 * 035 * @author Pete Cressman Copyright (C) 2014 036 */ 037public class PortalManager implements jmri.InstanceManagerAutoDefault, PropertyChangeListener { 038 039 private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); 040 private final ArrayList<Portal> _nameList = new ArrayList<>(); // stores Portal in loaded order 041 private final HashMap<String, Portal> _portalMap = new HashMap<>(); // stores portal by current name 042 043 public PortalManager() { 044 // no setup currently required 045 } 046 047 public int getPortalCount() { 048 return _nameList.size(); 049 } 050 051 public Portal getPortal(int idx) { 052 return _nameList.get(idx); 053 } 054 055 public int getIndexOf(Portal portal) { 056 return _nameList.indexOf(portal); 057 } 058 059 public Portal getPortal(String name) { 060 return _portalMap.get(name); 061 } 062 063 public Collection<Portal> getPortalSet() { 064 return Collections.unmodifiableCollection(_nameList); 065 } 066 067 /* 068 * Create a new Portal with a given user name. 069 * 070 * @return null if a Portal with the same userName already exists, 071 * or if an empty userName was requested 072 */ 073 public Portal createNewPortal(@Nonnull String userName) { 074 java.util.Objects.requireNonNull(userName, "Name cannot be null"); 075 // Check that Portal does not already exist 076 Portal portal; 077 if (userName.trim().length() > 0) { 078 portal = _portalMap.get(userName); 079 if (portal != null) { 080 return null; 081 } 082 } else { // must have a user name for backward compatibility 083 return null; 084 } 085 // Portal does not exist, create a new Portal 086 portal = new Portal(userName); 087 // save in the maps 088 _nameList.add(portal); 089 _portalMap.put(userName, portal); 090 pcs.firePropertyChange("numPortals", null, _nameList.size()); 091 // listen for name and state changes to forward 092 portal.addPropertyChangeListener(this); 093 return portal; 094 } 095 096 public Portal providePortal(String name) { 097 if (name == null || name.trim().length() == 0) { 098 return null; 099 } 100 Portal portal = getPortal(name); 101 if (portal == null) { 102 portal = createNewPortal(name); 103 } 104 return portal; 105 } 106 107 private synchronized void deletePortal(Portal portal) { 108 String name = portal.getName(); 109 _nameList.remove(portal); 110 _portalMap.remove(name); 111 pcs.firePropertyChange("numPortals", portal, _nameList.size()); 112 } 113 114 @OverridingMethodsMustInvokeSuper 115 public synchronized void addPropertyChangeListener(PropertyChangeListener l) { 116 pcs.addPropertyChangeListener(l); 117 } 118 119 @OverridingMethodsMustInvokeSuper 120 public synchronized void removePropertyChangeListener(PropertyChangeListener l) { 121 pcs.removePropertyChangeListener(l); 122 } 123 124 @Override 125 public void propertyChange(PropertyChangeEvent e) { 126 if (!(e.getSource() instanceof Portal)) { 127 return; 128 } 129 Portal portal = (Portal)e.getSource(); 130 String propertyName = e.getPropertyName(); 131 log.debug("property = {}", propertyName); 132 if (propertyName.equals("portalDelete")) { 133 deletePortal(portal); 134 } 135 } 136 137 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PortalManager.class); 138 139}