1 19 20 package org.netbeans.spi.project.ui.support; 21 22 import java.util.ArrayList ; 23 import java.util.Arrays ; 24 import java.util.Collection ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.List ; 28 import javax.swing.event.ChangeEvent ; 29 import javax.swing.event.ChangeListener ; 30 import org.netbeans.api.project.Project; 31 import org.openide.filesystems.FileObject; 32 import org.openide.filesystems.Repository; 33 import org.openide.loaders.DataFolder; 34 import org.openide.loaders.FolderLookup; 35 import org.openide.nodes.Children; 36 import org.openide.nodes.Node; 37 import org.openide.util.Lookup; 38 import org.openide.util.LookupEvent; 39 import org.openide.util.LookupListener; 40 41 47 public class NodeFactorySupport { 48 49 private NodeFactorySupport() { 50 } 51 52 60 public static Children createCompositeChildren(Project project, String folderPath) { 61 return new DelegateChildren(project, folderPath); 62 } 63 64 69 public static NodeList fixedNodeList(Node... nodes) { 70 return new FixedNodeList(nodes); 71 } 72 73 private static class FixedNodeList implements NodeList<Node> { 74 75 private List <Node> nodes; 76 77 FixedNodeList(Node... nds) { 78 nodes = Arrays.asList(nds); 79 } 80 public List <Node> keys() { 81 return nodes; 82 } 83 84 public void addChangeListener(ChangeListener l) { } 85 86 public void removeChangeListener(ChangeListener l) { } 87 88 public void addNotify() { 89 } 90 91 public void removeNotify() { 92 } 93 94 public Node node(Node key) { 95 return key; 96 } 97 } 98 99 static class DelegateChildren extends Children.Keys<NodeListKeyWrapper> implements LookupListener, ChangeListener { 100 101 private String folderPath; 102 private Project project; 103 private List <NodeList<?>> nodeLists = new ArrayList <NodeList<?>>(); 104 private List <NodeFactory> factories = new ArrayList <NodeFactory>(); 105 private Lookup.Result<NodeFactory> result; 106 private HashMap <NodeList<?>, List <NodeListKeyWrapper>> keys; 107 108 public DelegateChildren(Project proj, String path) { 109 folderPath = path; 110 project = proj; 111 } 112 113 protected Lookup createLookup() { 115 FileObject root = Repository.getDefault().getDefaultFileSystem().findResource(folderPath); 116 DataFolder folder = DataFolder.findFolder(root); 117 return new FolderLookup(folder).getLookup(); 118 } 119 120 protected Node[] createNodes(NodeListKeyWrapper key) { 121 Node nd = key.nodeList.node(key.object); 122 if (nd != null) { 123 return new Node[] { nd }; 124 } 125 return new Node[0]; 126 } 127 128 private Collection <NodeListKeyWrapper> createKeys() { 129 Collection <NodeListKeyWrapper> col = new ArrayList <NodeListKeyWrapper>(); 130 synchronized (keys) { 131 for (NodeList lst : nodeLists) { 132 List <NodeListKeyWrapper> x = keys.get(lst); 133 if (x != null) { 134 col.addAll(x); 135 } 136 } 137 } 138 return col; 139 } 140 141 protected void addNotify() { 142 super.addNotify(); 143 keys = new HashMap <NodeList<?>, List <NodeListKeyWrapper>>(); 144 result = createLookup().lookup(new Lookup.Template<NodeFactory>(NodeFactory.class)); 145 for (NodeFactory factory : result.allInstances()) { 146 NodeList<?> lst = factory.createNodes(project); 147 assert lst != null; 148 lst.addNotify(); 149 synchronized (keys) { 150 nodeLists.add(lst); 151 addKeys(lst); 152 } 153 lst.addChangeListener(this); 154 factories.add(factory); 155 } 156 result.addLookupListener(this); 157 setKeys(createKeys()); 158 } 159 160 protected void removeNotify() { 161 super.removeNotify(); 162 setKeys(Collections.<NodeListKeyWrapper>emptySet()); 163 for (NodeList elem : nodeLists) { 164 elem.removeChangeListener(this); 165 elem.removeNotify(); 166 } 167 synchronized (keys) { 168 keys.clear(); 169 nodeLists.clear(); 170 } 171 factories.clear(); 172 if (result != null) { 173 result.removeLookupListener(this); 174 result = null; 175 } 176 } 177 178 public void stateChanged(ChangeEvent e) { 179 NodeList list = (NodeList) e.getSource(); 180 synchronized (keys) { 181 removeKeys(list); 182 addKeys(list); 183 } 184 setKeys(createKeys()); 185 } 186 187 private void addKeys(NodeList list) { 189 List <NodeListKeyWrapper> wrps = new ArrayList <NodeListKeyWrapper>(); 190 for (Object key : list.keys()) { 191 wrps.add(new NodeListKeyWrapper(key, list)); 192 } 193 keys.put(list, wrps); 194 195 } 196 197 private void removeKeys(NodeList list) { 199 keys.remove(list); 200 } 201 202 203 public void resultChanged(LookupEvent ev) { 204 int index = 0; 205 for (NodeFactory factory : result.allInstances()) { 206 if (!factories.contains(factory)) { 207 factories.add(index, factory); 208 NodeList<?> lst = factory.createNodes(project); 209 assert lst != null; 210 synchronized (keys) { 211 nodeLists.add(index, lst); 212 addKeys(lst); 213 } 214 lst.addNotify(); 215 lst.addChangeListener(this); 216 } else { 217 while (!factory.equals(factories.get(index))) { 218 factories.remove(index); 219 synchronized (keys) { 220 NodeList<?> lst = nodeLists.remove(index); 221 removeKeys(lst); 222 lst.removeNotify(); 223 lst.removeChangeListener(this); 224 } 225 } 226 } 227 index++; 228 } 229 setKeys(createKeys()); 230 } 231 232 233 } 234 235 241 private static class NodeListKeyWrapper { 242 NodeList nodeList; 243 Object object; 244 NodeListKeyWrapper(Object obj, NodeList list) { 245 nodeList = list; 246 object = obj; 247 } 248 249 public boolean equals(Object obj) { 250 if (! (obj instanceof NodeListKeyWrapper)) { 251 return false; 252 } 253 NodeListKeyWrapper other = (NodeListKeyWrapper)obj; 254 if (! nodeList.equals(other.nodeList)) { 255 return false; 256 } 257 return object.equals(other.object); 258 } 259 260 public int hashCode() { 261 return (17 * 37 + nodeList.hashCode()) * 37 + object.hashCode(); 262 263 } 264 265 } 266 267 } 268 | Popular Tags |