/* * Copyright 2004-2012 the Seasar Foundation and the Others. * * 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 org.seasar.mayaa.impl.engine; import java.io.PrintStream; import java.util.Iterator; import org.seasar.mayaa.cycle.ServiceCycle; import org.seasar.mayaa.cycle.scope.RequestScope; import org.seasar.mayaa.cycle.script.CompiledScript; import org.seasar.mayaa.engine.Page; import org.seasar.mayaa.engine.Template; import org.seasar.mayaa.engine.processor.ProcessorProperty; import org.seasar.mayaa.engine.processor.ProcessorTreeWalker; import org.seasar.mayaa.engine.processor.TemplateProcessor; import org.seasar.mayaa.engine.specification.NodeAttribute; import org.seasar.mayaa.engine.specification.PrefixAwareName; import org.seasar.mayaa.engine.specification.PrefixMapping; import org.seasar.mayaa.engine.specification.QName; import org.seasar.mayaa.engine.specification.SpecificationNode; import org.seasar.mayaa.engine.specification.URI; import org.seasar.mayaa.impl.cycle.CycleUtil; import org.seasar.mayaa.impl.engine.processor.ElementProcessor; import org.seasar.mayaa.impl.engine.processor.LiteralCharactersProcessor; import org.seasar.mayaa.impl.util.StringUtil; /** * @author Koji Suga (Gluegent, Inc.) */ public class ProcessorDump extends ElementProcessor { // TODO EchoProcessorを継承して使っている部分をまとめる // TODO ServiceProviderで差し替え可能にする private static final long serialVersionUID = 8044884422670533823L; private static final PrintStream DEFAULT_OUT = System.out; private PrintStream _out = DEFAULT_OUT; private String _headerLine = "DUMPSTART ======================================="; private String _footerLine = "DUMPEND ========================================="; private String _indentChar = " "; private boolean _printContents = false; public void setOut(PrintStream out) { _out = out; } public void setIndentChar(String indentChar) { if (indentChar == null) { throw new IllegalStateException("indentChar is null"); } _indentChar = indentChar; } public void setPrintContents(boolean printContents) { _printContents = printContents; } public void printSource(Page topLevelPage) { ServiceCycle cycle = CycleUtil.getServiceCycle(); RequestScope request = cycle.getRequestScope(); String requestedSuffix = request.getRequestedSuffix(); String extension = request.getExtension(); Template template = topLevelPage.getTemplate(requestedSuffix, extension); print(_headerLine); print(template.getSystemID()); printTree(0, template); print(_footerLine); } protected void printTree(int indentCount, ProcessorTreeWalker walker) { // TODO レイアウト機能を使う場合 int childSize = walker.getChildProcessorSize(); if (walker instanceof TemplateProcessor) { printTag(indentCount, (TemplateProcessor) walker, "<", (childSize > 0 ? ">" : " />"), true); } if (childSize > 0) { for (int i = 0; i < childSize; i++) { printTree(indentCount + 1, walker.getChildProcessor(i)); } if (walker instanceof TemplateProcessor) { printTag(indentCount, (TemplateProcessor) walker, "</", ">", false); } } } protected void printTag( int indentCount, TemplateProcessor processor, String start, String end, boolean printAttributes) { if (_printContents && processor instanceof LiteralCharactersProcessor) { print(((LiteralCharactersProcessor) processor).getText()); // TODO insert の場合 // TODO echo の場合 } else { StringBuffer sb = new StringBuffer(128); for (int i = 0; i < indentCount; i++) { sb.append(_indentChar); } sb.append(start); SpecificationNode node = getNode(processor); String prefix = ""; PrefixMapping mapping = node.getMappingFromURI(node.getQName().getNamespaceURI(), true); if (mapping != null && StringUtil.hasValue(mapping.getPrefix())) { prefix = mapping.getPrefix() + ":"; } sb.append(prefix); sb.append(node.getQName().getLocalName()); if (printAttributes) { writeAttributes(sb, processor); } sb.append(end); if (false) {// TODO original sb.append("<!-- mayaa/original["); sb.append(processor.getOriginalNode().getQName().getLocalName()); sb.append("] -->"); } print(sb.toString()); } } protected SpecificationNode getNode(TemplateProcessor processor) { if (processor instanceof ElementProcessor) { ElementProcessor ep = (ElementProcessor) processor; if (ep.isDuplicated()) { // TODO templateElementもoriginalNodeにする // ep.getInjectedNode().getQName().equals(QM_TEMPLATE_ELEMENT) return processor.getOriginalNode(); } } return processor.getInjectedNode(); } protected void writeAttributes(StringBuffer sb, TemplateProcessor processor) { if (processor instanceof ElementProcessor) { writeElementAttributes(sb, (ElementProcessor) processor); } else { SpecificationNode node = processor.getInjectedNode(); URI namespace = node.getQName().getNamespaceURI(); for (Iterator it = processor.getInjectedNode().iterateAttribute(); it.hasNext();) { NodeAttribute prop = (NodeAttribute) it.next(); QName propName = prop.getQName(); String prefix = ""; if (namespace.equals(propName.getNamespaceURI()) == false) { PrefixMapping mapping = node.getMappingFromURI(propName.getNamespaceURI(), true); if (mapping != null && StringUtil.hasValue(mapping.getPrefix())) { prefix = mapping.getPrefix() + ":"; } } writeProcessorAttributeString( sb, prefix, propName.getLocalName(), prop.getValue()); } } } protected void writeElementAttributes(StringBuffer sb, ElementProcessor processor) { for (Iterator it = processor.iterateProcesstimeProperties(); it.hasNext();) { ProcessorProperty prop = (ProcessorProperty) it.next(); appendAttributeString(sb, prop.getName(), prop.getValue()); } for (Iterator it = processor.iterateInformalProperties(); it.hasNext();) { ProcessorProperty prop = (ProcessorProperty) it.next(); if (hasProcesstimeProperty(prop) == false && prop.getValue().isLiteral() == false) { appendAttributeString(sb, prop.getName(), prop.getValue()); } } for (Iterator it = processor.iterateInformalProperties(); it.hasNext();) { ProcessorProperty prop = (ProcessorProperty) it.next(); if (hasProcesstimeProperty(prop) == false && prop.getValue().isLiteral()) { appendAttributeString(sb, prop.getName(), prop.getValue()); } } } protected void appendAttributeString( StringBuffer buffer, PrefixAwareName propName, Object value) { QName qName = propName.getQName(); if (URI_MAYAA.equals(qName.getNamespaceURI())) { return; } // TODO 正しく描画する // if (getInjectedNode().getQName().equals(QM_DUPLECATED)) { // if (getChildProcessorSize() > 0 // && getChildProcessor(0) instanceof JspProcessor) { // JspProcessor processor = (JspProcessor)getChildProcessor(0); // URI injectNS = processor.getInjectedNode().getQName().getNamespaceURI(); // if (injectNS == qName.getNamespaceURI()) { // return; // } // } // } String attrPrefix = propName.getPrefix(); if (StringUtil.hasValue(attrPrefix)) { // attrPrefix = getResolvedPrefix(propName); if (StringUtil.hasValue(attrPrefix)) { attrPrefix = attrPrefix + ":"; } } StringBuffer temp = new StringBuffer(); temp.append(" "); temp.append(attrPrefix); temp.append(qName.getLocalName()); /* 2007.03.15 valueがnullの場合を許容する(値なしを作成可能に) */ if (value != null) { temp.append("=\""); if (value instanceof CompiledScript) { CompiledScript script = (CompiledScript) value; if (CycleUtil.isDraftWriting()) { temp.append(script.getScriptText()); } else { try { // TODO 修正する [JIRA: MAYAA-5] Object result = script.execute(null); if (StringUtil.isEmpty(result)) { return; } temp.append(result); } catch (Throwable ignore) { // no-op } } } else { temp.append(value.toString()); } temp.append("\""); } buffer.append(temp.toString()); } protected void writeProcessorAttributeString( StringBuffer sb, String prefix, String localName, Object value) { sb.append(" "); sb.append(prefix); sb.append(localName); sb.append("=\""); if (value instanceof CompiledScript) { CompiledScript script = (CompiledScript) value; sb.append(script.getScriptText()); } else { sb.append(value.toString()); } sb.append("\""); } protected void print(String value) { _out.println(value); } }