org.openide.util.lookup.implspi.NamedServicesProvider Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.openide.util.lookup.implspi;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;
/** Infrastructure provider interface for those who control the overall
* registration of services in the system. The first instance of this interface
* found in {@link Lookup#getDefault()} is consulted when providing answers
* to {@link Lookups#forPath(java.lang.String)} queries. Current implementation
* is not ready for multiple instances of this interface (the first one wins)
* and also changing the instances during runtime.
*
*
* The basic implementation of this interface is provided in
* Filesystem API
* and recognizes the
* .instance files
* registered in XML layers. As such one can rely on
* .instance files
* being recognized in unit tests, if the
* Filesystem API
* is included.
* The implementation
* is then refined in
* Settings API
* to handle also .settings files.
* Again, including this module in unit tests
* ensures
* .settings files
* files are recognized.
*
*
* @author Jaroslav Tulach
* @since 8.1
*/
public abstract class NamedServicesProvider {
private static final Map> namedServicesProviders = Collections.synchronizedMap(new HashMap>());
private static ThreadLocal IN = new ThreadLocal();
public static Lookup forPath(String path) {
Reference ref = namedServicesProviders.get(path);
Lookup lkp = ref == null ? null : ref.get();
if (lkp != null) {
return lkp;
}
NamedServicesProvider prov = Lookup.getDefault().lookup(NamedServicesProvider.class);
if (prov != null && IN.get() == null) {
IN.set(true);
try {
lkp = prov.create(path);
} finally {
IN.set(null);
}
} else {
ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
if (l == null) {
l = Thread.currentThread().getContextClassLoader();
if (l == null) {
l = NamedServicesProvider.class.getClassLoader();
}
}
lkp = Lookups.metaInfServices(l, "META-INF/namedservices/" + path);
}
namedServicesProviders.put(path, new WeakReference(lkp));
return lkp;
}
/** Finds a config object under given path.
* @param filePath path to .instance or .settings file
* @param type the requested type for given object
* @return either null or instance of requested type
* @since 8.10
*/
public static T getConfigObject(String filePath, Class type) {
NamedServicesProvider prov = Lookup.getDefault().lookup(NamedServicesProvider.class);
return prov != null ? prov.lookupObject(filePath, type) : null;
}
/** Allows the providers to donate a special lookup for a given object.
* Right now it is used only for obtaining FileObject.getLookup
.
*
* @param obj the object to find lookup for
* @return null
or new lookup to be associated with the obj
* @since 8.17
*/
public static Lookup createLookupFor(Object obj) {
NamedServicesProvider prov = Lookup.getDefault().lookup(NamedServicesProvider.class);
return prov != null ? prov.lookupFor(obj) : null;
}
static void clearCache() {
boolean assertsOn = false;
assert assertsOn = true;
if (!assertsOn) {
throw new IllegalStateException();
}
namedServicesProviders.clear();
}
/** Throws an exception. Prevents unwanted instantiation of this class
* by unknown subclasses.
*/
protected NamedServicesProvider() {
if (getClass().getName().equals("org.openide.util.lookup.PathInLookupTest$P")) { // NOI18N
// OK for tests
return;
}
if (getClass().getName().equals("org.openide.util.UtilitiesTest$NamedServicesProviderImpl")) { // NOI18N
// OK for tests
return;
}
if (getClass().getName().equals("org.netbeans.modules.openide.filesystems.RecognizeInstanceFiles")) { // NOI18N
// OK for openide.filesystems
return;
}
if (getClass().getName().equals("org.netbeans.modules.settings.RecognizeInstanceObjects")) { // NOI18N
// OK for settings
return;
}
throw new IllegalStateException();
}
/** Create the lookup for given path. Called as a result of query to
* {@link Lookups#forPath(java.lang.String)}.
*
* @param path the identification of the path
* @return the lookup representing objects in this path.
*/
protected abstract Lookup create(String path);
/** Finds a config object under given path. Called from {@link FileUtil#getConfigObject}.
* @param filePath path to .instance or .settings file
* @param type the requested type for given object
* @return either null or instance of requested type
* @since 8.10
*/
protected T lookupObject(String path, Class type) {
return create(path).lookup(type);
}
/** Method for providers to work in orchestration with {@link #createLookupFor(java.lang.Object)}.
* By default return null
.
*
* @param obj the object to find lookup for
* @return null
or new lookup to be associated with the obj
* @since 8.17
*/
protected Lookup lookupFor(Object obj) {
return null;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy