1 11 package org.eclipse.ui.texteditor.rulers; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Collections ; 16 import java.util.Comparator ; 17 import java.util.HashMap ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.ListIterator ; 21 import java.util.Map ; 22 import java.util.Set ; 23 24 import com.ibm.icu.text.MessageFormat; 25 26 import org.eclipse.core.runtime.Assert; 27 import org.eclipse.core.runtime.IConfigurationElement; 28 import org.eclipse.core.runtime.IExtensionRegistry; 29 import org.eclipse.core.runtime.IStatus; 30 import org.eclipse.core.runtime.InvalidRegistryObjectException; 31 import org.eclipse.core.runtime.Platform; 32 import org.eclipse.core.runtime.Status; 33 34 import org.eclipse.ui.internal.texteditor.TextEditorPlugin; 35 import org.eclipse.ui.internal.texteditor.rulers.DAG; 36 import org.eclipse.ui.internal.texteditor.rulers.ExtensionPointHelper; 37 import org.eclipse.ui.internal.texteditor.rulers.RulerColumnMessages; 38 import org.eclipse.ui.internal.texteditor.rulers.RulerColumnPlacementConstraint; 39 import org.eclipse.ui.texteditor.ConfigurationElementSorter; 40 41 47 public final class RulerColumnRegistry { 48 49 private static final String EXTENSION_POINT= "rulerColumns"; private static final String QUALIFIED_EXTENSION_POINT= TextEditorPlugin.PLUGIN_ID + '.' + EXTENSION_POINT; 51 52 53 private static RulerColumnRegistry fgSingleton= null; 54 55 63 public static synchronized RulerColumnRegistry getDefault() { 64 if (fgSingleton == null) { 65 fgSingleton= new RulerColumnRegistry(); 66 } 67 68 return fgSingleton; 69 } 70 71 75 private List fDescriptors= null; 76 79 private Map fDescriptorMap= null; 80 81 84 private boolean fLoaded= false; 85 86 89 RulerColumnRegistry() { 90 } 91 92 104 public List getColumnDescriptors() { 105 ensureExtensionPointRead(); 106 return fDescriptors; 107 } 108 109 117 public RulerColumnDescriptor getColumnDescriptor(String id) { 118 Assert.isLegal(id != null); 119 ensureExtensionPointRead(); 120 return (RulerColumnDescriptor) fDescriptorMap.get(id); 121 } 122 123 127 private void ensureExtensionPointRead() { 128 boolean reload; 129 synchronized (this) { 130 reload= !fLoaded; 131 fLoaded= true; 132 } 133 if (reload) 134 reload(); 135 } 136 137 144 public void reload() { 145 IExtensionRegistry registry= Platform.getExtensionRegistry(); 146 List elements= new ArrayList (Arrays.asList(registry.getConfigurationElementsFor(TextEditorPlugin.PLUGIN_ID, EXTENSION_POINT))); 147 148 List descriptors= new ArrayList (); 149 Map descriptorMap= new HashMap (); 150 151 for (Iterator iter= elements.iterator(); iter.hasNext();) { 152 IConfigurationElement element= (IConfigurationElement) iter.next(); 153 try { 154 RulerColumnDescriptor desc= new RulerColumnDescriptor(element, this); 155 String id= desc.getId(); 156 if (descriptorMap.containsKey(id)) { 157 noteDuplicateId(desc); 158 continue; 159 } 160 161 descriptors.add(desc); 162 descriptorMap.put(id, desc); 163 } catch (InvalidRegistryObjectException x) { 164 169 noteInvalidExtension(element, x); 170 } 171 } 172 173 sort(descriptors); 174 175 synchronized (this) { 176 fDescriptors= Collections.unmodifiableList(descriptors); 177 fDescriptorMap= Collections.unmodifiableMap(descriptorMap); 178 } 179 } 180 181 186 private void sort(List descriptors) { 187 193 ConfigurationElementSorter sorter= new ConfigurationElementSorter() { 194 public IConfigurationElement getConfigurationElement(Object object) { 195 return ((RulerColumnDescriptor) object).getConfigurationElement(); 196 } 197 }; 198 Object [] array= descriptors.toArray(); 199 sorter.sort(array); 200 201 Map descriptorsById= new HashMap (); 202 for (int i= 0; i < array.length; i++) { 203 RulerColumnDescriptor desc= (RulerColumnDescriptor) array[i]; 204 descriptorsById.put(desc.getId(), desc); 205 } 206 207 DAG dag= new DAG(); 208 for (int i= 0; i < array.length; i++) { 209 RulerColumnDescriptor desc= (RulerColumnDescriptor) array[i]; 210 dag.addVertex(desc); 211 212 Set before= desc.getPlacement().getConstraints(); 213 for (Iterator it= before.iterator(); it.hasNext();) { 214 RulerColumnPlacementConstraint constraint= (RulerColumnPlacementConstraint) it.next(); 215 String id= constraint.getId(); 216 RulerColumnDescriptor target= (RulerColumnDescriptor) descriptorsById.get(id); 217 if (target == null) { 218 noteUnknownTarget(desc, id); 219 } else { 220 boolean success; 221 if (constraint.isBefore()) 222 success= dag.addEdge(desc, target); 223 else 224 success= dag.addEdge(target, desc); 225 if (!success) 226 noteCycle(desc, target); 227 } 228 } 229 } 230 231 Comparator gravityComp= new Comparator () { 232 public int compare(Object o1, Object o2) { 233 float diff= ((RulerColumnDescriptor) o1).getPlacement().getGravity() - ((RulerColumnDescriptor) o2).getPlacement().getGravity(); 234 if (diff == 0) 235 return 0; 236 if (diff < 0) 237 return -1; 238 return 1; 239 } 240 }; 241 242 243 Set toProcess= dag.getSources(); 244 int index= 0; 245 while (!toProcess.isEmpty()) { 246 Object next= Collections.min(toProcess, gravityComp); 247 array[index]= next; 248 index++; 249 dag.removeVertex(next); 250 toProcess= dag.getSources(); 251 } 252 Assert.isTrue(index == array.length); 253 254 ListIterator it= descriptors.listIterator(); 255 for (int i= 0; i < index; i++) { 256 it.next(); 257 it.set(array[i]); 258 } 259 } 260 261 private void noteInvalidExtension(IConfigurationElement element, InvalidRegistryObjectException x) { 262 String message= MessageFormat.format(RulerColumnMessages.RulerColumnRegistry_invalid_msg, new Object [] {ExtensionPointHelper.findId(element)}); 263 warnUser(message, x); 264 } 265 266 private void noteUnknownTarget(RulerColumnDescriptor desc, String referencedId) { 267 String message= MessageFormat.format(RulerColumnMessages.RulerColumnRegistry_unresolved_placement_msg, new Object [] {QUALIFIED_EXTENSION_POINT, referencedId, desc.getName(), desc.getContributor()}); 268 warnUser(message, null); 269 } 270 271 private void noteCycle(RulerColumnDescriptor desc, RulerColumnDescriptor target) { 272 String message= MessageFormat.format(RulerColumnMessages.RulerColumnRegistry_cyclic_placement_msg, new Object [] {QUALIFIED_EXTENSION_POINT, target.getName(), desc.getName(), desc.getContributor()}); 273 warnUser(message, null); 274 } 275 276 private void noteDuplicateId(RulerColumnDescriptor desc) { 277 String message= MessageFormat.format(RulerColumnMessages.RulerColumnRegistry_duplicate_id_msg, new Object [] {QUALIFIED_EXTENSION_POINT, desc.getId(), desc.getContributor()}); 278 warnUser(message, null); 279 } 280 281 private void warnUser(String message, Exception exception) { 282 IStatus status= new Status(IStatus.WARNING, TextEditorPlugin.PLUGIN_ID, IStatus.OK, message, exception); 283 TextEditorPlugin.getDefault().getLog().log(status); 284 } 285 } 286 | Popular Tags |