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