1 19 20 package org.netbeans.modules.editor.impl; 21 22 import org.netbeans.modules.editor.*; 23 import java.awt.BorderLayout ; 24 import java.io.IOException ; 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 import javax.swing.BoxLayout ; 32 import javax.swing.JComponent ; 33 import javax.swing.JPanel ; 34 import javax.swing.event.ChangeEvent ; 35 import javax.swing.event.ChangeListener ; 36 import javax.swing.text.JTextComponent ; 37 import org.netbeans.api.editor.mimelookup.MimeLookup; 38 import org.netbeans.api.editor.mimelookup.MimePath; 39 import org.netbeans.editor.SideBarFactory; 40 import org.netbeans.editor.WeakEventListenerList; 41 import org.netbeans.spi.editor.mimelookup.InstanceProvider; 42 import org.openide.ErrorManager; 43 import org.openide.cookies.InstanceCookie; 44 import org.openide.filesystems.FileObject; 45 import org.openide.loaders.DataObject; 46 import org.openide.loaders.DataObjectNotFoundException; 47 import org.openide.util.Lookup; 48 import org.openide.util.LookupEvent; 49 import org.openide.util.LookupListener; 50 import org.openide.util.WeakListeners; 51 52 58 public final class CustomizableSideBar extends JPanel { 59 60 private static HashMap components = new HashMap (5); 61 private static HashMap lookupResults = new HashMap (5); 62 private static HashMap lookupListeners = new HashMap (5); private static HashMap changeListeners = new HashMap (5); 65 66 69 70 private CustomizableSideBar(List components, SideBarPosition position){ 71 BoxLayout bl = new javax.swing.BoxLayout (this, position.getAxis()); 72 setLayout(bl); 73 74 for (Iterator i = components.iterator(); i.hasNext(); ){ 75 add((JComponent ) i.next()); 76 } 77 } 78 79 80 private static WeakEventListenerList getListenerList(String mimeType){ 81 WeakEventListenerList listenerList; 82 synchronized (changeListeners){ 83 listenerList = (WeakEventListenerList)changeListeners.get(mimeType); 84 } 85 return listenerList; 86 } 87 88 94 public static void addChangeListener(String mimeType, ChangeListener l) { 95 WeakEventListenerList listenerList; 96 synchronized (changeListeners){ 97 listenerList = (WeakEventListenerList)changeListeners.get(mimeType); 98 if (listenerList == null){ 99 listenerList = new WeakEventListenerList(); 100 } 101 changeListeners.put(mimeType, listenerList); 102 } 103 104 listenerList.add(ChangeListener .class, l); 105 } 106 107 112 public static void removeChangeListener(String mimeType, ChangeListener l) { 113 WeakEventListenerList listenerList = getListenerList(mimeType); 114 if (listenerList == null){ 115 return; 116 } 117 listenerList.remove(ChangeListener .class, l); 118 } 119 120 private static void fireChange(String mimeType) { 121 WeakEventListenerList listenerList = getListenerList(mimeType); 122 if (listenerList == null){ 123 return; 124 } 125 ChangeListener [] listeners 126 = (ChangeListener [])listenerList.getListeners(ChangeListener .class); 127 ChangeEvent evt = new ChangeEvent (CustomizableSideBar.class); 128 for (int i = 0; i < listeners.length; i++) { 129 listeners[i].stateChanged(evt); 130 } 131 } 132 133 134 public static Map createSideBars(JTextComponent target) { 135 Map components = getPanelComponents(target); 136 Map result = new HashMap (); 137 138 for (Iterator entries = components.entrySet().iterator(); entries.hasNext(); ) { 139 Map.Entry entry = (Map.Entry ) entries.next(); 140 SideBarPosition position = (SideBarPosition) entry.getKey(); 141 142 result.put(position, new CustomizableSideBar((List ) entry.getValue(), position)); 143 } 144 145 return result; 146 } 147 148 private static Map getInstanceCookiesPerKitClass(String mimeType){ 149 Map result = new HashMap (); 150 if (mimeType == null) return result; 151 synchronized (components){ 152 if (components.containsKey(mimeType)){ 153 return (Map )components.get(mimeType); 154 }else{ 155 Lookup lookup = MimeLookup.getLookup(MimePath.parse(mimeType)); 156 157 Lookup.Result lookupResult; 158 synchronized (lookupResults){ 159 lookupResult = (Lookup.Result)lookupResults.get(mimeType); 160 if (lookupResult == null){ 161 lookupResult = lookup.lookup(new Lookup.Template(SideBarFactoryProvider.class)); 162 lookupResults.put(mimeType, lookupResult); 163 } 164 } 165 166 Collection instances = lookupResult.allInstances(); 167 if (instances.isEmpty()){ 168 return result; } 170 171 SideBarFactoryProvider provider = (SideBarFactoryProvider) instances.iterator().next(); 172 173 synchronized (lookupListeners){ 174 LookupListener lookupListener = (LookupListener) lookupListeners.get(mimeType); 175 if (lookupListener == null){ 176 lookupListener = new MyLookupListener(mimeType); 177 LookupListener weakListener = (LookupListener) WeakListeners.create( 178 LookupListener.class, lookupListener, lookupResult); 179 lookupResult.addLookupListener(weakListener); 180 lookupListeners.put(mimeType, lookupListener); 181 } 182 } 183 184 if (provider!=null){ 185 result = provider.getProviders(); 186 } 187 188 if (result!=null){ 189 components.put(mimeType, result); 190 } 191 192 return result; 193 } 194 } 195 } 196 197 private static Map getPanelComponents(JTextComponent target){ 198 Map result = new HashMap (); 199 Map icMap = getInstanceCookiesPerKitClass(NbEditorUtilities.getMimeType(target)); 200 201 try{ 202 for (Iterator entries = icMap.entrySet().iterator(); entries.hasNext(); ) { 203 Map.Entry entry = (Map.Entry ) entries.next(); 204 List icList = (List ) entry.getValue(); 205 List retList = new ArrayList (); 206 207 for (int i = 0; i<icList.size(); i++){ 208 InstanceCookie ic = (InstanceCookie)icList.get(i); 209 Object obj = ic.instanceCreate(); 210 JComponent sideBarObj = ((SideBarFactory)obj).createSideBar(target); 211 if (sideBarObj!=null){ 212 retList.add(sideBarObj); 213 } 214 } 215 result.put(entry.getKey(), retList); 216 } 217 }catch(IOException ioe){ 218 ioe.printStackTrace(); 219 }catch(ClassNotFoundException cnfe){ 220 cnfe.printStackTrace(); 221 } 222 223 return result; 224 } 225 226 public static final class SideBarPosition { 227 public static final int WEST = 1; 228 public static final int NORTH = 2; 229 public static final int SOUTH = 3; 230 public static final int EAST = 4; 231 232 public static final String WEST_NAME = "West"; public static final String NORTH_NAME = "North"; public static final String SOUTH_NAME = "South"; public static final String EAST_NAME = "East"; 237 private int position; 238 private boolean scrollable; 239 240 SideBarPosition(FileObject fo) { 241 Object position = fo.getAttribute("position"); 243 if (position != null && position instanceof String ) { 244 String positionName = (String ) position; 245 246 if (WEST_NAME.equals(positionName)) { 247 this.position = WEST; 248 } else { 249 if (NORTH_NAME.equals(positionName)) { 250 this.position = NORTH; 251 } else { 252 if (SOUTH_NAME.equals(positionName)) { 253 this.position = SOUTH; 254 } else { 255 if (EAST_NAME.equals(positionName)) { 256 this.position = EAST; 257 } else { 258 if (ErrorManager.getDefault().isLoggable(ErrorManager.INFORMATIONAL)) 259 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "Unsupported position: " + positionName); 260 261 this.position = WEST; 262 } 263 } 264 } 265 } 266 } else { 267 this.position = WEST; 268 } 269 270 Object scrollable = fo.getAttribute("scrollable"); 272 if (scrollable != null && scrollable instanceof Boolean ) { 273 this.scrollable = ((Boolean ) scrollable).booleanValue(); 274 } else { 275 this.scrollable = true; 276 } 277 278 if (this.scrollable && (this.position == SOUTH || this.position == EAST)) { 279 if (ErrorManager.getDefault().isLoggable(ErrorManager.INFORMATIONAL)) 280 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "Unsupported combination: scrollable == true, position=" + getBorderLayoutPosition()); 281 } 282 } 283 284 public int hashCode() { 285 return scrollable ? position : - position; 286 } 287 288 public boolean equals(Object o) { 289 if (o instanceof SideBarPosition) { 290 SideBarPosition p = (SideBarPosition) o; 291 292 if (scrollable != p.scrollable) 293 return false; 294 295 if (position != p.position) 296 return false; 297 298 return true; 299 } 300 301 return false; 302 } 303 304 public int getPosition() { 305 return position; 306 } 307 308 private static String [] borderLayoutConstants = new String [] {"", BorderLayout.WEST, BorderLayout.NORTH, BorderLayout.SOUTH, BorderLayout.EAST}; 309 310 public String getBorderLayoutPosition() { 311 return borderLayoutConstants[getPosition()]; 312 } 313 314 private static int[] axisConstants = new int[] {-1, BoxLayout.X_AXIS, BoxLayout.Y_AXIS, BoxLayout.Y_AXIS, BoxLayout.X_AXIS}; 315 316 private int getAxis() { 317 return axisConstants[getPosition()]; 318 } 319 320 public boolean isScrollable() { 321 return scrollable; 322 } 323 324 public String toString() { 325 return "[SideBarPosition: scrollable=" + scrollable + ", position=" + position + "]"; } 327 } 328 329 public static class SideBarFactoryProvider implements InstanceProvider{ 330 331 List ordered; 332 333 public SideBarFactoryProvider(){ 334 } 335 336 public SideBarFactoryProvider(List ordered){ 337 this.ordered = ordered; 338 } 339 340 public Map getProviders(){ 341 Map result = new HashMap (); 342 for (int i = 0; i<ordered.size(); i++){ 343 FileObject fo = (FileObject) ordered.get(i); 344 345 DataObject dob; 346 try { 347 dob = DataObject.find(fo); 348 } catch (DataObjectNotFoundException dnfe) { 349 continue; 351 } 352 353 InstanceCookie ic = (InstanceCookie)dob.getCookie(InstanceCookie.class); 354 if (ic!=null){ 355 try{ 356 if (SideBarFactory.class.isAssignableFrom(ic.instanceClass() )){ 357 SideBarPosition position = new SideBarPosition(dob.getPrimaryFile()); 358 359 List retList = (List ) result.get(position); 360 361 if (retList == null) { 362 result.put(position, retList = new ArrayList ()); 363 } 364 365 retList.add(ic); 366 } 367 }catch(IOException ioe){ 368 ioe.printStackTrace(); 369 }catch(ClassNotFoundException cnfe){ 370 cnfe.printStackTrace(); 371 } 372 } 373 } 374 return result; 375 } 376 377 public Object createInstance(List ordered) { 378 return new SideBarFactoryProvider(ordered); 379 } 380 } 381 382 private static class MyLookupListener implements LookupListener{ 383 private String mimeType; 384 public MyLookupListener(String mimeType){ 385 this.mimeType = mimeType; 386 } 387 388 public void resultChanged(LookupEvent ev) { 389 synchronized (components){ 390 components.remove(mimeType); 391 } 392 fireChange(mimeType); 393 } 394 } 395 396 } 397 | Popular Tags |