/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed 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 com.alibaba.citrus.dev.handler.impl;
import static com.alibaba.citrus.dev.handler.util.ReflectionUtil.*;
import static com.alibaba.citrus.util.BasicConstant.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static com.alibaba.citrus.util.StringUtil.join;
import static com.alibaba.citrus.util.StringUtil.*;
import java.util.List;
import java.util.Map;
import com.alibaba.citrus.dev.handler.component.AccessControlComponent;
import com.alibaba.citrus.dev.handler.component.DomComponent;
import com.alibaba.citrus.dev.handler.component.TabsComponent;
import com.alibaba.citrus.dev.handler.component.TabsComponent.TabItem;
import com.alibaba.citrus.util.FileUtil;
import com.alibaba.citrus.util.templatelite.Template;
import com.alibaba.citrus.webx.WebxComponent;
import com.alibaba.citrus.webx.WebxComponents;
import com.alibaba.citrus.webx.handler.RequestHandlerContext;
import com.alibaba.citrus.webx.handler.support.AbstractVisitor;
import com.alibaba.citrus.webx.handler.support.LayoutRequestProcessor;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.AbstractApplicationContext;
public abstract class AbstractExplorerHandler extends LayoutRequestProcessor {
protected final TabsComponent tabsComponent = new TabsComponent(this, "tabs");
protected final DomComponent domComponent = new DomComponent(this, "dom");
protected final AccessControlComponent aclComponent = new AccessControlComponent(this, "acl");
@Autowired
private WebxComponents components;
public WebxComponents getWebxComponents() {
return components;
}
@Override
protected abstract AbstractExplorerVisitor getBodyVisitor(RequestHandlerContext context);
@Override
protected String getTitle(Object bodyVisitor) {
AbstractExplorerVisitor visitor = (AbstractExplorerVisitor) bodyVisitor;
String contextName = visitor.currentContextName;
if (contextName == null) {
return visitor.currentFunctionName + " - Root Context - " + visitor.getConfigLocationString();
} else {
return visitor.currentFunctionName + " - " + contextName + " - " + visitor.getConfigLocationString();
}
}
protected String getFunctionName(String functionName) {
functionName = trimToNull(functionName);
if (!getAvailableFunctions().containsKey(functionName)) {
functionName = getDefaultFunction();
}
return functionName;
}
protected String link(String contextName, String functionName) {
StringBuilder buf = new StringBuilder("?");
if (contextName != null) {
buf.append("context=").append(contextName);
}
functionName = getFunctionName(functionName);
if (!getDefaultFunction().equals(functionName)) {
if (buf.length() > 1) {
buf.append("&");
}
buf.append("fn=").append(functionName);
}
return buf.toString();
}
protected abstract Map<String, String> getAvailableFunctions();
protected abstract String getDefaultFunction();
protected abstract class AbstractExplorerVisitor extends AbstractVisitor {
protected final String currentFunctionName;
protected final String currentContextName;
protected final WebxComponent currentComponent;
protected final AbstractApplicationContext appcontext;
protected final String[] configLocations;
public AbstractExplorerVisitor(RequestHandlerContext context) {
super(context);
// 取得当前的component信息
String contextName = trimToNull(context.getRequest().getParameter("context"));
WebxComponent component = getWebxComponents().getComponent(contextName);
if (component == null) {
currentContextName = null;
} else {
currentContextName = component.getName();
}
currentComponent = getWebxComponents().getComponent(currentContextName);
// 取得当前的功能
this.currentFunctionName = getFunctionName(context.getRequest().getParameter("fn"));
// 取得context信息
this.appcontext = (AbstractApplicationContext) currentComponent.getApplicationContext();
// 取得config locations
String[] locations;
try {
locations = normalizeConfigLocations(String[].class.cast(getAccessibleMethod(
this.appcontext.getClass(), "getConfigLocations", EMPTY_CLASS_ARRAY).invoke(this.appcontext,
EMPTY_OBJECT_ARRAY)));
} catch (Exception e) {
locations = EMPTY_STRING_ARRAY;
}
this.configLocations = locations;
}
public AbstractApplicationContext getApplicationContext() {
return appcontext;
}
public TabsComponent getTabsComponent() {
return tabsComponent;
}
public DomComponent getDomComponent() {
return domComponent;
}
protected String getConfigLocationString() {
return join(configLocations, ", ");
}
public void visitTabs() {
List<TabItem> tabs = createLinkedList();
for (String fn : getAvailableFunctions().keySet()) {
TabItem tab = new TabItem(getAvailableFunctions().get(fn));
tab.setHref(link(currentContextName, fn));
tab.setSelected(fn.equals(currentFunctionName));
tabs.add(tab);
// root context
TabItem subtab = new TabItem("Root Context");
subtab.setHref(link(null, fn));
subtab.setSelected(currentContextName == null);
tab.addSubTab(subtab);
// all sub-contexts
for (String contextName : getWebxComponents().getComponentNames()) {
subtab = new TabItem(contextName);
subtab.setHref(link(contextName, fn));
subtab.setSelected(contextName.equals(currentContextName));
tab.addSubTab(subtab);
}
}
tabsComponent.visitTemplate(context, tabs);
}
public void visitContextName() {
out().print(currentContextName == null ? "Root Context" : currentContextName);
}
public void visitContextNameForParam() {
out().print(currentContextName == null ? "" : currentContextName);
}
public void visitFunctionName() {
out().print(currentFunctionName);
}
public void visitConfigLocations() {
out().print(getConfigLocationString());
}
public final void visitExplorer(Template[] functionTemplates) {
if (!aclComponent.accessAllowed(context)) {
return;
}
String[] functions = getAvailableFunctions().keySet().toArray(new String[getAvailableFunctions().size()]);
for (int i = 0; i < functions.length && i < functionTemplates.length; i++) {
String function = functions[i];
if (function.equals(currentFunctionName)) {
functionTemplates[i].accept(this);
}
}
}
protected final <S> S getService(String name, Class<S> type) {
try {
return type.cast(appcontext.getBean(name));
} catch (NoSuchBeanDefinitionException e) {
return null;
}
}
private String[] normalizeConfigLocations(String[] locations) {
for (int i = 0; i < locations.length; i++) {
String location = locations[i];
int index = location.indexOf(":");
if (index >= 0) {
location = location.substring(0, index + 1)
+ FileUtil.normalizeAbsolutePath(location.substring(index + 1));
} else {
location = FileUtil.normalizeAbsolutePath(location);
}
locations[i] = location;
}
return locations;
}
}
}