import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import javax.servlet.ServletContext;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.runtime.RuntimeConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.WebApplicationContext;
import com.alibaba.citrus.service.resource.Resource;
import com.alibaba.citrus.service.resource.ResourceLoader;
import com.alibaba.citrus.service.resource.ResourceLoaderContext;
import com.alibaba.citrus.service.resource.ResourceLoadingOption;
import com.alibaba.citrus.service.resource.ResourceLoadingService;
import com.alibaba.citrus.service.resource.support.InputStreamResource;
import com.alibaba.citrus.service.template.TemplateService;
import com.alibaba.citrus.service.velocity.impl.VelocityEngineImpl;
import com.alibaba.citrus.service.velocity.impl.VelocityRuntimeInstance;
import static org.springframework.web.context.WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
/**
*
* @author yankai913@gmail.com
* @date 2016年4月11日
*/
public class HttpResourceLoader implements ResourceLoader, ServletContextAware,
ApplicationListener<ContextRefreshedEvent> {
private static final Logger logger = LoggerFactory.getLogger(HttpResourceLoader. class );
String resourceRemoteHost = "http://localhost:6666" ;
String vmEncoding = "UTF-8" ;
String[] additionalPathArr = new String[] { "" , "/common" };
ApplicationContext applicationContext;
ServletContext servletContext;
@Override
public void init(ResourceLoadingService resourceLoadingService) {
}
@Override
public Resource getResource(ResourceLoaderContext context, Set<ResourceLoadingOption> options) {
String resourceName = context.getResourceName();
try {
for (String additionalPath : additionalPathArr) {
String remoteFileURL = this .resourceRemoteHost + additionalPath + resourceName;
HttpUtils.HttpResult httpRequest =
HttpUtils.httpGet(remoteFileURL, null , null , vmEncoding, 3000 );
if (httpRequest.code == HttpURLConnection.HTTP_OK) {
String htmlText = httpRequest.content;
wrapHtmlContent(resourceName, htmlText);
ByteArrayInputStream bais = new ByteArrayInputStream(htmlText.getBytes(vmEncoding));
InputStreamResource resource = new PrototypeInputStreamResource(bais);
return resource;
} else {
continue ;
}
}
throw new IOException( "http get template failed! resourceName=" + resourceName);
} catch (Exception e) {
logger.error( "http get template failed! resourceName=" + resourceName + e.getMessage(), e);
}
return null ;
}
void wrapHtmlContent(String resourceName, String htmlText) {
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
String timestamp = sdf.format( new Date());
String content = "<!-- http get " + resourceName + "\t" + timestamp + " start -->\n" ;
content = content + htmlText;
content = "\n<!-- http get " + resourceName + "\t" + timestamp + " end -->\n" ;
}
@Override
public void setServletContext(ServletContext servletContext) {
this .servletContext = servletContext;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (event.getApplicationContext().getParent() == null ) {
WebApplicationContext wac =
(WebApplicationContext) servletContext
.getAttribute(ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
TemplateService ts = (TemplateService) wac.getBean( "templateService" );
VelocityEngineImpl ve = (VelocityEngineImpl) ts.getTemplateEngine( "vm" );
VelocityRuntimeInstance vri = (VelocityRuntimeInstance) ve.getRuntimeServices();
vmEncoding = StringUtils.trimToNull((String) vri.getProperty(RuntimeConstants.INPUT_ENCODING));
}
}
// 保证实时数据,不缓存。
static class PrototypeInputStreamResource extends InputStreamResource {
public PrototypeInputStreamResource(InputStream stream) {
super (stream);
}
public long lastModified() {
return System.currentTimeMillis();
}
}
}
|