下面列出了javax.ws.rs.core.Application#getClasses() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private synchronized void buildApiClasses(Application app) {
if (apiClasses == null) {
apiClasses = new HashSet<>();
if (app != null) {
Set<Class<?>> classes = app.getClasses();
if (classes != null) {
addAnnotatedClasses(apiClasses, classes);
}
Set<Object> singletons = app.getSingletons();
if (singletons != null) {
for (Object o : singletons) {
addAnnotatedClasses(apiClasses, Arrays.<Class<?>>asList(o.getClass()));
}
}
}
}
}
public static List<SourceType<Type>> scanJaxrsApplication(Class<?> jaxrsApplicationClass, Predicate<String> isClassNameExcluded) {
final ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(jaxrsApplicationClass.getClassLoader());
TypeScriptGenerator.getLogger().info("Scanning JAX-RS application: " + jaxrsApplicationClass.getName());
final Constructor<?> constructor = jaxrsApplicationClass.getDeclaredConstructor();
constructor.setAccessible(true);
final Application application = (Application) constructor.newInstance();
final List<Class<?>> resourceClasses = new ArrayList<>();
for (Class<?> cls : application.getClasses()) {
if (cls.isAnnotationPresent(Path.class)) {
resourceClasses.add(cls);
}
}
return new JaxrsApplicationScanner().scanJaxrsApplication(jaxrsApplicationClass, resourceClasses, isClassNameExcluded);
} catch (ReflectiveOperationException e) {
throw reportError(e);
} finally {
Thread.currentThread().setContextClassLoader(originalContextClassLoader);
}
}
@Test
public void testScanComponents() {
StringBuilder classPath = new StringBuilder();
classPath.append(Thread.currentThread().getContextClassLoader().getResource("scan/").toString());
ServletContext servletContext = mock(ServletContext.class);
when(servletContext.getInitParameter(EVERREST_GROOVY_ROOT_RESOURCES)).thenReturn(classPath.toString());
when(servletContext.getInitParameter(EVERREST_GROOVY_SCAN_COMPONENTS)).thenReturn("true");
GroovyEverrestServletContextInitializer initializer = new GroovyEverrestServletContextInitializer(servletContext);
Application application = initializer.getApplication();
Set<Class<?>> classes = application.getClasses();
assertNotNull(classes);
assertEquals(2, classes.size());
java.util.List<String> l = new ArrayList<>(2);
l.addAll(classes.stream().map(Class::getName).collect(Collectors.toList()));
assertTrue(l.contains("org.everrest.A"));
assertTrue(l.contains("org.everrest.B"));
}
private void separateProvidersAndResources(Application application, List<Class<?>> resourceClasses, List<Object> providerInstances) {
Set<Class<?>> classes = application.getClasses();
for (Class<?> clazz : classes) {
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().equals(Provider.class)) {
// for providers we have to create an instance
try {
providerInstances.add(clazz.newInstance());
break;
} catch (Exception e) {
throw new RuntimeException(e);
}
} else if (annotation.annotationType().equals(Path.class)) {
resourceClasses.add(clazz);
break;
}
}
}
}
@GET
@Timed
@Produces(MediaType.APPLICATION_JSON)
public String getProfile(@Context Application application) {
// May init multi times by multi threads, but no effect on the results
if (SERVER_PROFILES != null) {
return SERVER_PROFILES;
}
Map<String, Object> profiles = InsertionOrderUtil.newMap();
profiles.put("service", SERVICE);
profiles.put("version", CoreVersion.VERSION.toString());
profiles.put("doc", DOC);
profiles.put("api_doc", API_DOC);
Set<String> apis = new TreeSet<>();
for (Class<?> clazz : application.getClasses()) {
if (!isAnnotatedPathClass(clazz)) {
continue;
}
Resource resource = Resource.from(clazz);
APICategory apiCategory = APICategory.parse(resource.getName());
apis.add(apiCategory.dir);
}
profiles.put("apis", apis);
SERVER_PROFILES = JsonUtil.toJson(profiles);
return SERVER_PROFILES;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public ResourceIndex index(@Context Application application,
@Context HttpServletRequest request) throws Exception {
JsonObject rootNode = new JsonObject();
JsonArray classesNode = new JsonArray();
rootNode.addProperty(JS_TITLE_FIELD, Settings.getString(SettingCodes.API_TITLE, Bundle.SETTINGS, DefaultSettings.API_TITLE));
rootNode.addProperty(JS_INSTANCE_FIELD, WebUtil.getInstanceName());
rootNode.addProperty(JS_VERSION_FIELD, Settings.getString(SettingCodes.API_VERSION, Bundle.SETTINGS, DefaultSettings.API_VERSION));
rootNode.addProperty(JS_JVM_FIELD, System.getProperty("java.version"));
rootNode.addProperty(JS_REALM_FIELD, Settings.getString(SettingCodes.API_REALM, Bundle.SETTINGS, DefaultSettings.API_REALM));
AnnouncementVO announcement = WebUtil.getServiceLocator().getToolsService().getAnnouncement();
if (announcement != null) {
rootNode.addProperty(JS_ANNOUNCEMENT_FIELD, announcement.getMessage());
}
rootNode.add(JS_CLASSES_FIELD, classesNode);
ArrayList<Class<?>> classes = new ArrayList<>(application.getClasses());
Collections.sort(classes, RESOURCE_CLASS_COMPARATOR);
Iterator<Class<?>> classesIt = classes.iterator();
while (classesIt.hasNext()) {
Class<?> resourceClass = classesIt.next();
if (isAnnotatedResourceClass(resourceClass)) {
classesNode.add(getResourceIndexNode(resourceClass, request));
}
}
return new ResourceIndex(rootNode);
}
/**
* JAX-RS application has defined singletons as being classes of any providers, resources and features.
* In the JAXRSServerFactoryBean, those should be split around several method calls depending on instance
* type. At the moment, only the Feature is CXF-specific and should be replaced by JAX-RS Feature implementation.
* @param application the application instance
* @return classified instances of classes by instance types
*/
private ClassifiedClasses classes2singletons(final Application application, final BeanManager beanManager) {
final ClassifiedClasses classified = new ClassifiedClasses();
// now loop through the classes
Set<Class<?>> classes = application.getClasses();
if (!classes.isEmpty()) {
classified.addProviders(loadProviders(beanManager, classes));
classified.addFeatures(loadFeatures(beanManager, classes));
for (final Bean< ? > bean: serviceBeans) {
if (classes.contains(bean.getBeanClass())) {
// normal scoped beans will return us a proxy in getInstance so it is singletons for us,
// @Singleton is indeed a singleton
// @Dependent should be a request scoped instance but for backward compat we kept it a singleton
//
// other scopes are considered request scoped (for jaxrs)
// and are created per request (getInstance/releaseInstance)
final ResourceProvider resourceProvider;
if (isCxfSingleton(beanManager, bean)) {
final Lifecycle lifecycle = new Lifecycle(beanManager, bean);
resourceProvider = new SingletonResourceProvider(lifecycle, bean.getBeanClass());
// if not a singleton we manage it per request
// if @Singleton the container handles it
// so we only need this case here
if (Dependent.class == bean.getScope()) {
disposableLifecycles.add(lifecycle);
}
} else {
resourceProvider = new PerRequestResourceProvider(
() -> new Lifecycle(beanManager, bean), bean.getBeanClass());
}
classified.addResourceProvider(resourceProvider);
}
}
}
return classified;
}
@Override
protected void createServerFromApplication(ServletConfig servletConfig) throws ServletException {
Application app = new DPCXFApplication();
configurable.register(new DPCXFContainerResponseFilter(), ContainerResponseFilter.class);
List<Class<?>> resourceClasses = new ArrayList<>();
Map<Class<?>, ResourceProvider> map = new HashMap<>();
List<Feature> features = new ArrayList<>();
for (Object o : app.getSingletons()) {
ResourceProvider rp = new SingletonResourceProvider(o);
for (Class<?> c : app.getClasses()) {
resourceClasses.add(c);
map.put(c, rp);
}
}
JAXRSServerFactoryBean bean = createJAXRSServerFactoryBean();
bean.setBus(getBus());
bean.setAddress("/");
bean.setResourceClasses(resourceClasses);
bean.setFeatures(features);
for (Map.Entry<Class<?>, ResourceProvider> entry : map.entrySet()) {
bean.setResourceProvider(entry.getKey(), entry.getValue());
}
Map<String, Object> appProps = app.getProperties();
if (appProps != null) {
bean.getProperties(true).putAll(appProps);
}
bean.setApplication(app);
CXFServerConfiguration configuration = (CXFServerConfiguration) this.configurable.getConfiguration();
bean.setProviders(new ArrayList<Object>(configuration.getExtensions()));
bean.create();
}
@SuppressWarnings("unchecked")
public static JAXRSServerFactoryBean createApplication(Application app,
boolean ignoreAppPath,
boolean staticSubresourceResolution,
boolean useSingletonResourceProvider,
Bus bus) {
Set<Object> singletons = app.getSingletons();
verifySingletons(singletons);
List<Class<?>> resourceClasses = new ArrayList<>();
List<Object> providers = new ArrayList<>();
List<Feature> features = new ArrayList<>();
Map<Class<?>, ResourceProvider> map = new HashMap<>();
// Note, app.getClasses() returns a list of per-request classes
// or singleton provider classes
for (Class<?> cls : app.getClasses()) {
if (isValidApplicationClass(cls, singletons)) {
if (isValidProvider(cls)) {
providers.add(createProviderInstance(cls));
} else if (Feature.class.isAssignableFrom(cls)) {
features.add(createFeatureInstance((Class<? extends Feature>) cls));
} else {
resourceClasses.add(cls);
if (useSingletonResourceProvider) {
map.put(cls, new SingletonResourceProvider(createProviderInstance(cls)));
} else {
map.put(cls, new PerRequestResourceProvider(cls));
}
}
}
}
// we can get either a provider or resource class here
for (Object o : singletons) {
if (isValidProvider(o.getClass())) {
providers.add(o);
} else if (o instanceof Feature) {
features.add((Feature) o);
} else {
resourceClasses.add(o.getClass());
map.put(o.getClass(), new SingletonResourceProvider(o));
}
}
JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean();
if (bus != null) {
bean.setBus(bus);
}
String address = "/";
if (!ignoreAppPath) {
ApplicationPath appPath = locateApplicationPath(app.getClass());
if (appPath != null) {
address = appPath.value();
}
}
if (!address.startsWith("/")) {
address = "/" + address;
}
bean.setAddress(address);
bean.setStaticSubresourceResolution(staticSubresourceResolution);
bean.setResourceClasses(resourceClasses);
bean.setProviders(providers);
bean.getFeatures().addAll(features);
for (Map.Entry<Class<?>, ResourceProvider> entry : map.entrySet()) {
bean.setResourceProvider(entry.getKey(), entry.getValue());
}
Map<String, Object> appProps = app.getProperties();
if (appProps != null) {
bean.getProperties(true).putAll(appProps);
}
bean.setApplication(app);
return bean;
}
@Override
public void initialize(Server server, Bus bus) {
final JAXRSServiceFactoryBean sfb = (JAXRSServiceFactoryBean)server
.getEndpoint()
.get(JAXRSServiceFactoryBean.class.getName());
final ServerProviderFactory factory = (ServerProviderFactory)server
.getEndpoint()
.get(ServerProviderFactory.class.getName());
final Set<String> packages = new HashSet<>();
if (resourcePackages != null) {
packages.addAll(resourcePackages);
}
final Application application = DefaultApplicationFactory.createApplicationOrDefault(server, factory,
sfb, bus, resourcePackages, isScan());
final AnnotationProcessor processor = new AnnotationProcessor(GeronimoOpenAPIConfig.create(),
new NamingStrategy.Http(), null /* default JsonReaderFactory */);
final OpenAPIImpl api = new OpenAPIImpl();
if (isScan()) {
packages.addAll(scanResourcePackages(sfb));
}
final Set<Class<?>> resources = new HashSet<>();
if (application != null) {
processor.processApplication(api, new ClassElement(application.getClass()));
LOG.fine("Processed application " + application);
if (application.getClasses() != null) {
resources.addAll(application.getClasses());
}
}
resources.addAll(sfb
.getClassResourceInfo()
.stream()
.map(AbstractResourceInfo::getServiceClass)
.filter(cls -> filterByPackage(cls, packages))
.filter(cls -> filterByClassName(cls, resourceClasses))
.collect(Collectors.toSet()));
if (!resources.isEmpty()) {
final String binding = (application == null) ? ""
: processor.getApplicationBinding(application.getClass());
resources
.stream()
.peek(c -> LOG.info("Processing class " + c.getName()))
.forEach(c -> processor.processClass(binding, api, new ClassElement(c),
Stream.of(c.getMethods()).map(MethodElement::new)));
} else {
LOG.warning("No resource classes registered, the OpenAPI will not contain any endpoints.");
}
Properties swaggerProps = getSwaggerProperties(propertiesLocation, bus);
if (api.getInfo() == null) {
api.setInfo(getInfo(swaggerProps));
}
registerOpenApiResources(sfb, api);
registerSwaggerUiResources(sfb, swaggerProps, factory, bus);
}
/**
* Add components defined by <code>application</code> to this instance.
*
* @param application
* application
* @see javax.ws.rs.core.Application
*/
public void addApplication(Application application) {
if (application != null) {
Set<Object> appSingletons = application.getSingletons();
if (appSingletons != null && !appSingletons.isEmpty()) {
Set<Object> allSingletons = new LinkedHashSet<>(this.singletons.size() + appSingletons.size());
allSingletons.addAll(appSingletons);
allSingletons.addAll(this.singletons);
this.singletons.clear();
this.singletons.addAll(allSingletons);
}
Set<Class<?>> appClasses = application.getClasses();
if (appClasses != null && !appClasses.isEmpty()) {
Set<Class<?>> allClasses = new LinkedHashSet<>(this.classes.size() + appClasses.size());
allClasses.addAll(appClasses);
allClasses.addAll(this.classes);
this.classes.clear();
this.classes.addAll(allClasses);
}
if (application instanceof EverrestApplication) {
EverrestApplication everrest = (EverrestApplication)application;
Set<ObjectFactory<? extends ObjectModel>> appFactories = everrest.getFactories();
if (!appFactories.isEmpty()) {
Set<ObjectFactory<? extends ObjectModel>> allFactories = new LinkedHashSet<>(this.factories.size() + appFactories.size());
allFactories.addAll(appFactories);
allFactories.addAll(this.factories);
this.factories.clear();
this.factories.addAll(allFactories);
}
Map<String, Class<?>> appResourceClasses = everrest.getResourceClasses();
if (!appResourceClasses.isEmpty()) {
Map<String, Class<?>> allResourceClasses = new LinkedHashMap<>(this.resourceClasses.size() + appResourceClasses.size());
allResourceClasses.putAll(appResourceClasses);
allResourceClasses.putAll(this.resourceClasses);
this.resourceClasses.clear();
this.resourceClasses.putAll(allResourceClasses);
}
Map<String, Object> appResourceSingletons = everrest.getResourceSingletons();
if (!appResourceSingletons.isEmpty()) {
Map<String, Object> allResourceSingletons = new LinkedHashMap<>(this.resourceSingletons.size() + appResourceSingletons.size());
allResourceSingletons.putAll(appResourceSingletons);
allResourceSingletons.putAll(this.resourceSingletons);
this.resourceSingletons.clear();
this.resourceSingletons.putAll(allResourceSingletons);
}
}
}
}