1 /******************************************************************************* 2 * Copyright (c) 2007, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.ui.texteditor; 15 16 import java.util.ArrayList; 17 import java.util.List; 18 19 import org.eclipse.core.runtime.Assert; 20 import org.eclipse.core.runtime.CoreException; 21 import org.eclipse.core.runtime.IAdaptable; 22 23 import org.eclipse.jface.preference.IPreferenceStore; 24 25 import org.eclipse.jface.text.IRegion; 26 import org.eclipse.jface.text.ITextViewer; 27 import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; 28 import org.eclipse.jface.text.hyperlink.IHyperlink; 29 import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; 30 import org.eclipse.jface.text.hyperlink.IHyperlinkDetectorExtension; 31 import org.eclipse.jface.text.hyperlink.IHyperlinkDetectorExtension2; 32 33 34 35 /** 36 * Hyperlink detector registry that manages the detectors 37 * contributed by the <code>org.eclipse.ui.workbench.texteditor.hyperlinkDetectors</code> extension point for 38 * targets contributed by the <code>org.eclipse.ui.workbench.texteditor.hyperlinkDetectorTargets</code> extension point. 39 * 40 * @since 3.3 41 */ 42 public final class HyperlinkDetectorRegistry { 43 44 45 /** 46 * Delegate for contributed hyperlink detectors. 47 */ 48 private class HyperlinkDetectorDelegate implements IHyperlinkDetector, IHyperlinkDetectorExtension, IHyperlinkDetectorExtension2 { 49 50 private HyperlinkDetectorDescriptor fHyperlinkDescriptor; 51 private IHyperlinkDetector fHyperlinkDetector; 52 private boolean fFailedDuringCreation= false; 53 private IAdaptable fContext; 54 private int fStateMask; 55 private boolean fIsEnabled; 56 57 HyperlinkDetectorDelegate(HyperlinkDetectorDescriptor descriptor)58 private HyperlinkDetectorDelegate(HyperlinkDetectorDescriptor descriptor) { 59 fHyperlinkDescriptor= descriptor; 60 if (fPreferenceStore != null) { 61 fStateMask= fPreferenceStore.getInt(fHyperlinkDescriptor.getId() + HyperlinkDetectorDescriptor.STATE_MASK_POSTFIX); 62 fIsEnabled= !fPreferenceStore.getBoolean(fHyperlinkDescriptor.getId()); 63 } 64 } 65 66 @Override detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks)67 public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { 68 if (!isEnabled()) 69 return null; 70 71 if (!fFailedDuringCreation && fHyperlinkDetector == null) { 72 try { 73 fHyperlinkDetector= fHyperlinkDescriptor.createHyperlinkDetectorImplementation(); 74 } catch (CoreException ex) { 75 fFailedDuringCreation= true; 76 } 77 if (fContext != null && fHyperlinkDetector instanceof AbstractHyperlinkDetector) 78 ((AbstractHyperlinkDetector)fHyperlinkDetector).setContext(fContext); 79 } 80 if (fHyperlinkDetector != null) 81 return fHyperlinkDetector.detectHyperlinks(textViewer, region, canShowMultipleHyperlinks); 82 83 return null; 84 } 85 isEnabled()86 private boolean isEnabled() { 87 return fIsEnabled; 88 } 89 setContext(IAdaptable context)90 private void setContext(IAdaptable context) { 91 fContext= context; 92 } 93 94 @Override dispose()95 public void dispose() { 96 if (fHyperlinkDetector instanceof AbstractHyperlinkDetector) 97 ((AbstractHyperlinkDetector)fHyperlinkDetector).dispose(); 98 99 fHyperlinkDetector= null; 100 fHyperlinkDescriptor= null; 101 fContext= null; 102 } 103 104 @Override getStateMask()105 public int getStateMask() { 106 return fStateMask; 107 } 108 109 } 110 111 112 private HyperlinkDetectorDescriptor[] fHyperlinkDetectorDescriptors; 113 private IPreferenceStore fPreferenceStore; 114 115 116 /** 117 * Creates a new hyperlink detector registry. 118 */ HyperlinkDetectorRegistry()119 public HyperlinkDetectorRegistry() { 120 } 121 122 /** 123 * Creates a new hyperlink detector registry that controls 124 * hyperlink enablement via the given preference store. 125 * <p> 126 * The hyperlink detector id is used as preference key. 127 * The value is of type <code>Boolean</code> where 128 * <code>false</code> means that the hyperlink detector is active. 129 * </p> 130 * 131 * @param preferenceStore the preference store to be used 132 */ HyperlinkDetectorRegistry(IPreferenceStore preferenceStore)133 public HyperlinkDetectorRegistry(IPreferenceStore preferenceStore) { 134 fPreferenceStore= preferenceStore; 135 } 136 137 /** 138 * Returns all hyperlink detectors contributed to the workbench. 139 * 140 * @return an array of hyperlink detector descriptors 141 */ getHyperlinkDetectorDescriptors()142 public synchronized HyperlinkDetectorDescriptor[] getHyperlinkDetectorDescriptors() { 143 initHyperlinkDetectorDescriptors(); 144 HyperlinkDetectorDescriptor[] result= new HyperlinkDetectorDescriptor[fHyperlinkDetectorDescriptors.length]; 145 System.arraycopy(fHyperlinkDetectorDescriptors, 0, result, 0, fHyperlinkDetectorDescriptors.length); 146 return result; 147 } 148 149 /** 150 * Initializes the hyperlink detector descriptors. 151 */ initHyperlinkDetectorDescriptors()152 private synchronized void initHyperlinkDetectorDescriptors() { 153 if (fHyperlinkDetectorDescriptors == null) 154 fHyperlinkDetectorDescriptors= HyperlinkDetectorDescriptor.getContributedHyperlinkDetectors(); 155 } 156 157 /* 158 * @see org.eclipse.jface.text.hyperlink.IHyperlinkDetectorRegistry#createHyperlinkDetectors(java.lang.String[], org.eclipse.core.runtime.IAdaptable) 159 */ createHyperlinkDetectors(String targetId, IAdaptable context)160 public IHyperlinkDetector[] createHyperlinkDetectors(String targetId, IAdaptable context) { 161 Assert.isLegal(targetId != null); 162 initHyperlinkDetectorDescriptors(); 163 164 List<HyperlinkDetectorDelegate> result= new ArrayList<>(); 165 for (int i= 0; i < fHyperlinkDetectorDescriptors.length; i++) { 166 if (targetId.equals(fHyperlinkDetectorDescriptors[i].getTargetId())) { 167 HyperlinkDetectorDelegate detector= new HyperlinkDetectorDelegate(fHyperlinkDetectorDescriptors[i]); 168 result.add(detector); 169 detector.setContext(context); 170 } 171 } 172 return result.toArray(new IHyperlinkDetector[result.size()]); 173 } 174 175 } 176