Bug 564062 - Refactor ContentTypeManager.DEBUGGING The ContentTypeManager DEBUGGING field is initialised as soon as the class is loaded. This may be too eager since it may not be needed until later. By moving the boolean into a static inner class, we can defer its initialisation until the first time it is used in a code path. We can also take advantage of Equinox's new `ServiceCaller` which allows for single-shot access of services. Change-Id: Iea9b52894f796c8b5cc6ad1fbdf248aafa745b4f Signed-off-by: Alex Blewitt <alex.blewitt@gmail.com>
diff --git a/bundles/org.eclipse.core.contenttype/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.contenttype/META-INF/MANIFEST.MF index 795ed5e..5180ff3 100644 --- a/bundles/org.eclipse.core.contenttype/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.core.contenttype/META-INF/MANIFEST.MF
@@ -7,7 +7,7 @@ Bundle-Localization: plugin Require-Bundle: org.eclipse.equinox.preferences;bundle-version="[3.2.0,4.0.0)", org.eclipse.equinox.registry;bundle-version="[3.2.0,4.0.0)", - org.eclipse.equinox.common;bundle-version="[3.2.0,4.0.0)" + org.eclipse.equinox.common;bundle-version="[3.13.0,4.0.0)" Export-Package: org.eclipse.core.internal.content;x-internal:=true, org.eclipse.core.runtime.content Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentType.java b/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentType.java index c3ac68e..7759cf3 100644 --- a/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentType.java +++ b/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentType.java
@@ -192,7 +192,7 @@ throw llioe.getActualException(); } catch (IOException ioe) { // bugs 67841/ 62443 - non-low level IOException should be "ignored" - if (ContentTypeManager.DEBUGGING) { + if (ContentTypeManager.DebuggingHolder.DEBUGGING) { String message = NLS.bind(ContentMessages.content_errorReadingContents, id); ContentType.log(message, ioe); } @@ -630,7 +630,7 @@ void setValidation(byte validation) { this.validation = validation; - if (ContentTypeManager.DEBUGGING) + if (ContentTypeManager.DebuggingHolder.DEBUGGING) ContentMessages.message("Validating " + this + ": " + getValidationString(validation)); //$NON-NLS-1$ //$NON-NLS-2$ }
diff --git a/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeBuilder.java b/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeBuilder.java index 496d569..85c237a 100644 --- a/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeBuilder.java +++ b/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeBuilder.java
@@ -19,7 +19,8 @@ import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.core.runtime.preferences.*; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.osgi.util.NLS; import org.osgi.service.prefs.BackingStoreException; @@ -165,7 +166,7 @@ String propertyKey = propertyCE.getAttribute("name"); //$NON-NLS-1$ QualifiedName qualifiedKey = parseQualifiedName(namespace, propertyKey); if (qualifiedKey == null) { - if (ContentTypeManager.DEBUGGING) { + if (ContentTypeManager.DebuggingHolder.DEBUGGING) { String message = NLS.bind(ContentMessages.content_invalidProperty, propertyKey, getUniqueId(namespace, simpleId)); ContentType.log(message, null); }
diff --git a/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeCatalog.java b/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeCatalog.java index e173b5f..37ae65e 100644 --- a/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeCatalog.java +++ b/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeCatalog.java
@@ -660,7 +660,7 @@ if (ensureValid(type)) associate(type); } - if (ContentTypeManager.DEBUGGING) + if (ContentTypeManager.DebuggingHolder.DEBUGGING) for (IContentType iContentType : contentTypes.values()) { ContentType type = (ContentType) iContentType; if (!type.isValid())
diff --git a/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeManager.java b/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeManager.java index 89214da..013835e 100644 --- a/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeManager.java +++ b/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeManager.java
@@ -23,7 +23,6 @@ import org.eclipse.core.runtime.preferences.*; import org.eclipse.osgi.service.debug.DebugOptions; import org.eclipse.osgi.util.NLS; -import org.osgi.framework.*; import org.osgi.service.prefs.BackingStoreException; public class ContentTypeManager extends ContentTypeMatcher implements IContentTypeManager { @@ -47,21 +46,24 @@ public static final int BLOCK_SIZE = 0x400; public static final String CONTENT_TYPE_PREF_NODE = IContentConstants.RUNTIME_NAME + IPath.SEPARATOR + "content-types"; //$NON-NLS-1$ private static final String OPTION_DEBUG_CONTENT_TYPES = "org.eclipse.core.contenttype/debug"; //$NON-NLS-1$ - static final boolean DEBUGGING; private ContentTypeCatalog catalog; private int catalogGeneration; - static { - boolean debugging = false; - Bundle bundle = FrameworkUtil.getBundle(ContentTypeManager.class); - BundleContext context = bundle == null ? null : bundle.getBundleContext(); - ServiceReference<DebugOptions> reference = context.getServiceReference(DebugOptions.class); - DebugOptions debugOptions = reference == null ? null : context.getService(reference); - if (debugOptions != null) { - debugging = debugOptions.getBooleanOption(OPTION_DEBUG_CONTENT_TYPES, false); - context.ungetService(reference); + /** + * The DebuggingHolder contains a single boolean with a + * {@link DebuggingHolder#DEBUGGING} field. By providing a class that wraps it, + * it will defer the lookup of this field until it is needed. + */ + static class DebuggingHolder { + static final boolean DEBUGGING; + static { + boolean[] debugging = { false }; + ServiceCaller.callOnce(DebuggingHolder.class, DebugOptions.class, + (debugOptions) -> { + debugging[0] = debugOptions.getBooleanOption(OPTION_DEBUG_CONTENT_TYPES, false); + }); + DEBUGGING = debugging[0]; } - DEBUGGING = debugging; } /** @@ -196,7 +198,7 @@ * Causes a new catalog to be built afresh next time an API call is made. */ synchronized void invalidate() { - if (ContentTypeManager.DEBUGGING && catalog != null) + if (DebuggingHolder.DEBUGGING && catalog != null) ContentMessages.message("Registry discarded"); //$NON-NLS-1$ catalog = null; }