@ -3,11 +3,50 @@ package com.fanruan.boot.adaptation;
import com.fanruan.carina.Carina ;
import com.fanruan.carina.annotions.FineComponent ;
import com.fanruan.carina.annotions.Start ;
import com.fanruan.plugins.resource.PluginResourceHelper ;
import com.fanruan.portal.FinePortal ;
import com.fanruan.portal.module.PortalModule ;
import com.fr.base.ServerConfig ;
import com.fr.decision.ExtraDecisionClassManager ;
import com.fr.decision.base.VirtualFilterChain ;
import com.fr.decision.fun.EmbedRequestFilterProvider ;
import com.fr.decision.fun.GlobalRequestFilterProvider ;
import com.fr.decision.fun.SystemOptionProvider ;
import com.fr.decision.plugin.PluginControllerManager ;
import com.fr.decision.portal.PluginPortalModuleDevice ;
import com.fr.event.Event ;
import com.fr.event.EventDispatcher ;
import com.fr.event.Listener ;
import com.fr.general.I18nResource ;
import com.fr.general.InterProviderImpl ;
import com.fr.locale.InterMutableKey ;
import com.fr.locale.LocaleMarker ;
import com.fr.locale.LocaleScope ;
import com.fr.plugin.ExtraClassManager ;
import com.fr.plugin.context.PluginContext ;
import com.fr.plugin.injectable.PluginModule ;
import com.fr.plugin.observer.PluginEventType ;
import com.fr.stable.StringUtils ;
import com.fr.stable.collections.CollectionUtils ;
import javax.servlet.DispatcherType ;
import javax.servlet.Filter ;
import javax.servlet.FilterChain ;
import javax.servlet.FilterConfig ;
import javax.servlet.FilterRegistration ;
import javax.servlet.ServletContext ;
import javax.servlet.ServletException ;
import javax.servlet.ServletRequest ;
import javax.servlet.ServletResponse ;
import javax.servlet.http.HttpServletRequest ;
import javax.servlet.http.HttpServletResponse ;
import java.io.IOException ;
import java.util.ArrayList ;
import java.util.EnumSet ;
import java.util.LinkedHashSet ;
import java.util.Map ;
import java.util.Set ;
import java.util.TreeSet ;
/ * *
* 用于内置服务器检查并适配其他FR服务细节的模块
@ -26,8 +65,125 @@ public class ReportAdaptationComponent {
@Start
public void start ( ) {
checkI18n ( ) ;
// 注册插件定义的门户模块
registerPluginModules ( ) ;
//注册filter插件
listenEmbedServletFilter ( Carina . getApplicationContext ( ) . getServletContext ( ) ) ;
listenGlobalServletFilter ( Carina . getApplicationContext ( ) . getServletContext ( ) ) ;
// 插件controller注册
PluginControllerManager . getInstance ( ) . init ( ) ;
}
private void listenEmbedServletFilter ( ServletContext servletContext ) {
final Set < EmbedRequestFilterProvider > set = new LinkedHashSet < > ( ExtraDecisionClassManager . getInstance ( ) . getArray ( EmbedRequestFilterProvider . MARK_STRING ) ) ;
final FilterConfig [ ] embedFilterConfig = new FilterConfig [ 1 ] ;
com . fr . stable . Filter < PluginContext > filter = new com . fr . stable . Filter < PluginContext > ( ) {
@Override
public boolean accept ( PluginContext context ) {
return context . contain ( PluginModule . ExtraDecision , EmbedRequestFilterProvider . MARK_STRING ) ;
}
} ;
EventDispatcher . listen ( PluginEventType . AfterRun , new Listener < PluginContext > ( ) {
@Override
public void on ( Event event , PluginContext context ) {
Set < EmbedRequestFilterProvider > providers = context . getRuntime ( ) . get ( PluginModule . ExtraDecision , EmbedRequestFilterProvider . MARK_STRING ) ;
providers . forEach ( provider - > provider . init ( embedFilterConfig [ 0 ] ) ) ;
set . addAll ( providers ) ;
}
} , filter ) ;
EventDispatcher . listen ( PluginEventType . BeforeStop , new Listener < PluginContext > ( ) {
@Override
public void on ( Event event , PluginContext context ) {
Set < EmbedRequestFilterProvider > providers = context . getRuntime ( ) . get ( PluginModule . ExtraDecision , EmbedRequestFilterProvider . MARK_STRING ) ;
providers . forEach ( EmbedRequestFilterProvider : : destroy ) ;
set . removeAll ( providers ) ;
}
} , filter ) ;
FilterRegistration . Dynamic servletFilter = servletContext . addFilter ( ServerConfig . getInstance ( ) . getServletName ( ) , new Filter ( ) {
@Override
public void init ( FilterConfig filterConfig ) {
embedFilterConfig [ 0 ] = filterConfig ;
for ( EmbedRequestFilterProvider one : set ) {
one . init ( filterConfig ) ;
}
}
@Override
public void doFilter ( ServletRequest servletRequest , ServletResponse servletResponse , FilterChain filterChain ) throws IOException , ServletException {
VirtualFilterChain virtualFilterChain = new VirtualFilterChain ( new ArrayList < > ( set ) , filterChain ) ;
virtualFilterChain . doFilter ( servletRequest , servletResponse ) ;
}
@Override
public void destroy ( ) {
for ( EmbedRequestFilterProvider one : set ) {
one . destroy ( ) ;
}
}
} ) ;
EnumSet < DispatcherType > dispatcherTypes = EnumSet . of ( DispatcherType . REQUEST , DispatcherType . FORWARD , DispatcherType . ERROR ) ;
servletFilter . addMappingForUrlPatterns ( dispatcherTypes , false , ServerConfig . getInstance ( ) . getServletMapping ( ) ) ;
}
private void listenGlobalServletFilter ( ServletContext servletContext ) {
final Set < GlobalRequestFilterProvider > set = ExtraDecisionClassManager . getInstance ( ) . getArray ( GlobalRequestFilterProvider . MARK_STRING ) ;
final Set < GlobalRequestFilterProvider > sort = new TreeSet < > ( set ) ;
for ( final GlobalRequestFilterProvider provider : sort ) {
String externalFilterClassName = provider . externalFilterClassName ( ) ;
FilterRegistration . Dynamic servletFilter ;
if ( StringUtils . isBlank ( externalFilterClassName ) ) {
servletFilter = servletContext . addFilter ( provider . filterName ( ) , new Filter ( ) {
@Override
public void init ( FilterConfig filterConfig ) throws ServletException {
provider . init ( filterConfig ) ;
}
@Override
public void doFilter ( ServletRequest servletRequest , ServletResponse servletResponse , FilterChain filterChain ) throws IOException , ServletException {
provider . doFilter ( ( HttpServletRequest ) servletRequest , ( HttpServletResponse ) servletResponse , filterChain ) ;
}
@Override
public void destroy ( ) {
provider . destroy ( ) ;
}
} ) ;
} else {
servletFilter = servletContext . addFilter ( provider . filterName ( ) , externalFilterClassName ) ;
}
Map < String , String > parameters = provider . initializationParameters ( ) ;
if ( parameters ! = null ) {
servletFilter . setInitParameters ( provider . initializationParameters ( ) ) ;
}
EnumSet < DispatcherType > dispatcherTypes = EnumSet . of ( DispatcherType . REQUEST , DispatcherType . FORWARD , DispatcherType . ERROR ) ;
servletFilter . addMappingForUrlPatterns ( dispatcherTypes , false , provider . urlPatterns ( ) ) ;
}
}
private void registerPluginModules ( ) {
// 注册插件模块
try {
Set < SystemOptionProvider > systemOptionProviders = ExtraClassManager . getInstance ( ) . getArray ( SystemOptionProvider . XML_TAG ) ;
if ( ! CollectionUtils . isEmpty ( systemOptionProviders ) ) {
// 资源引入采用新的方式,WebCoalition接口不再继承使用,这里只处理模块注册
for ( SystemOptionProvider optionProvider : systemOptionProviders ) {
PortalModule portalModule = PortalModule . create ( optionProvider . id ( ) , optionProvider . displayName ( ) )
. sortIndex ( optionProvider . sortIndex ( ) )
. dynamicControl ( m - > new PluginPortalModuleDevice ( optionProvider . parentId ( ) , m ) ) ;
FinePortal . registerModule ( optionProvider . parentId ( ) , portalModule ) ;
// 插件资源注册
PluginResourceHelper . getInstance ( ) . registerAtom2Portal ( optionProvider ) ;
}
}
} catch ( Exception e ) {
throw new RuntimeException ( e ) ;
}
}
private void checkI18n ( ) {
for ( LocaleMarker marker : Carina . getApplicationContext ( ) . group ( InterMutableKey . class ) . getAll ( ) ) {
if ( marker . match ( LocaleScope . SERVER ) ) {