/* * 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.visitor; import static com.alibaba.citrus.util.BasicConstant.*; import static com.alibaba.citrus.util.ClassUtil.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static com.alibaba.citrus.util.ExceptionUtil.*; import static com.alibaba.citrus.util.ObjectUtil.*; import static com.alibaba.citrus.util.StringEscapeUtil.*; import static com.alibaba.citrus.util.StringUtil.*; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.Set; import com.alibaba.citrus.dev.handler.impl.ExplorerHandler.ExplorerVisitor; import com.alibaba.citrus.service.pull.PullContext; import com.alibaba.citrus.service.pull.PullService; import com.alibaba.citrus.util.templatelite.Template; import com.alibaba.citrus.webx.handler.RequestHandlerContext; public class PullToolsVisitor extends AbstractFallbackVisitor<ExplorerVisitor> { private final PullService tools; private final Entry rootEntry; private Entry entry; public PullToolsVisitor(RequestHandlerContext context, ExplorerVisitor v, PullService tools) { super(context, v); this.tools = tools; this.rootEntry = new Entry(null); PullContext pullContext = tools.getContext(); boolean parentEntry = false; String[] names = pullContext.getQualifiedToolNames().toArray(EMPTY_STRING_ARRAY); Arrays.sort(names, new Comparator<String>() { public int compare(String o1, String o2) { int p1 = o1.startsWith("/_parent/") ? 1 : 0; int p2 = o2.startsWith("/_parent/") ? 1 : 0; if (p1 == p2) { return o1.compareTo(o2); } else { return p1 - p2; } } }); for (String path : names) { Entry entry = rootEntry; String[] pathsegs = split(path, "/"); String name = null; for (String pathseg : pathsegs) { name = pathseg; Entry subEntry = entry.subEntries.get(name); if (subEntry == null) { subEntry = new Entry(name); entry.subEntries.put(name, subEntry); } entry = subEntry; if (!parentEntry) { if ("_parent".equals(entry.name)) { parentEntry = true; } } entry.parentEntry = parentEntry; } try { entry.value = pullContext.pull(name); } catch (Exception e) { entry.value = e; } } } public void visitService(Template serviceNotAvailableTemplate, Template serviceTemplate) { if (tools == null) { serviceNotAvailableTemplate.accept(this); } else { entry = rootEntry; serviceTemplate.accept(this); } } public void visitTool(Template toolTemplate) { for (Iterator<Entry> i = entry.subEntries.values().iterator(); i.hasNext(); ) { entry = i.next(); toolTemplate.accept(this); } } public void visitToolName(Template toolWithValueTemplate, Template toolWithoutValueTemplate) { if (entry.value != null) { toolWithValueTemplate.accept(this); } else { toolWithoutValueTemplate.accept(this); } } public void visitToolHidden(Template toolHiddenTemplate) { if (entry.parentEntry && entry.value != null && visitedName.contains(entry.name)) { toolHiddenTemplate.accept(this); } } private Set<String> visitedName = createHashSet(); public void visitName() { String name = entry.name; if (entry.parentEntry) { if ("_parent".equals(entry.name)) { name = "Inherited from Parent Context"; } } else { if (entry.value != null) { visitedName.add(name); } } out().print(escapeHtml(name)); } public void visitSubTools(Template subToolsTemplate) { if (!entry.subEntries.isEmpty()) { subToolsTemplate.accept(this); } } public void visitToolValue(Template toolValueTemplate) { if (entry.value != null) { toolValueTemplate.accept(this); } } public void visitValueTypePackage() { try { if (entry.value != null) { out().print(entry.value.getClass().getPackage().getName() + "."); } } catch (NullPointerException e) { } } public void visitValueTypeName() { out().print(getSimpleClassName(entry.value.getClass(), false)); } public void visitValue() { String s; if (entry.value instanceof Throwable) { s = getStackTrace(getRootCause((Throwable) entry.value)); } else { s = entry.value.toString(); } out().print(escapeHtml(s)); } public void visitToolId() { out().print(identityHashCode(entry)); } private class Entry { private final String name; private final Map<String, Entry> subEntries = createLinkedHashMap(); private Object value; private boolean parentEntry; public Entry(String name) { this.name = trimToNull(name); } } }