/* * 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.processor; import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.seasar.mayaa.builder.PathAdjuster; import org.seasar.mayaa.builder.SequenceIDGenerator; import org.seasar.mayaa.builder.library.LibraryDefinition; import org.seasar.mayaa.builder.library.ProcessorDefinition; import org.seasar.mayaa.builder.library.converter.PropertyConverter; import org.seasar.mayaa.cycle.script.CompiledScript; import org.seasar.mayaa.engine.processor.ProcessorProperty; import org.seasar.mayaa.engine.processor.ProcessorTreeWalker; import org.seasar.mayaa.engine.specification.NodeAttribute; import org.seasar.mayaa.engine.specification.PrefixAwareName; import org.seasar.mayaa.engine.specification.QName; import org.seasar.mayaa.engine.specification.SpecificationNode; import org.seasar.mayaa.impl.cycle.CycleUtil; import org.seasar.mayaa.impl.cycle.script.LiteralScript; import org.seasar.mayaa.impl.engine.specification.SpecificationUtil; import org.seasar.mayaa.impl.provider.ProviderUtil; import org.seasar.mayaa.impl.util.StringUtil; /** * @author Koji Suga (Gluegent, Inc.) */ public class EchoProcessor extends ElementProcessor { private static final long serialVersionUID = 3924111635172574833L; private PrefixAwareName _customName; public void setOriginalNode(SpecificationNode originalNode) { super.setOriginalNode(originalNode); setupElement(originalNode); } protected PropertyConverter getConverterForProcessorProperty() { ProcessorDefinition processorDef = getProcessorDefinition(); LibraryDefinition libraryDef = processorDef.getLibraryDefinition(); PropertyConverter converter = libraryDef.getPropertyConverter(ProcessorProperty.class); if (converter == null) { throw new IllegalStateException(); } return converter; } /** * テンプレート上の属性に相対パス調整が必要な場合、調整して返します。 * 必要なければそのまま返します。 * * @param adjuster パス調整クラス * @param originalNode テンプレート上の対象要素 * @param attribute テンプレート上の対象属性 * @return 相対パス調整済み対象属性の値 */ protected String getAdjustedValue(PathAdjuster adjuster, SpecificationNode originalNode, NodeAttribute attribute) { String value = attribute.getValue(); QName nodeName = originalNode.getQName(); if (adjuster.isTargetNode(nodeName)) { QName attributeName = attribute.getQName(); if (adjuster.isTargetAttribute(nodeName, attributeName)) { String contextPath = CycleUtil.getRequestScope().getContextPath(); String basePath = contextPath + originalNode.getSystemID(); return adjuster.adjustRelativePath(basePath, value); } } return value; } /** * 対応するテンプレートの要素の属性をinformal propertyに追加します。 * * @param originalNode 対応するテンプレートの要素 */ protected void setupElement(SpecificationNode originalNode) { if (_customName != null) { super.setName(_customName); } else { // メモリ消費軽減と速度性能アップのためにキャッシュ利用 PrefixAwareName prefixAwareName = SpecificationUtil.createPrefixAwareName( originalNode.getQName(), originalNode.getPrefix()); super.setName(prefixAwareName); } PropertyConverter converter = getConverterForProcessorProperty(); PathAdjuster adjuster = ProviderUtil.getPathAdjuster(); for (Iterator it = originalNode.iterateAttribute(); it.hasNext();) { NodeAttribute attribute = (NodeAttribute) it.next(); String value = getAdjustedValue(adjuster, originalNode, attribute); Class expectedClass = getExpectedClass(); Serializable property = converter.convert(attribute, value, expectedClass); PrefixAwareName propName = SpecificationUtil.createPrefixAwareName( attribute.getQName(), attribute.getPrefix()); super.addInformalProperty(propName, property); } } // MLD property of ElementProcessor public void setName(PrefixAwareName name) { _customName = name; } // MLD method of AbstractAttributableProcessor public void addInformalProperty(PrefixAwareName name, Object attr) { // doNothing } // ProcessorTreeWalker implements -------------------------------- public Map getVariables() { Iterator it = iterateInformalProperties(); if (it.hasNext()) { Map attributeMap = new HashMap(); while (it.hasNext()) { ProcessorProperty prop = (ProcessorProperty) it.next(); attributeMap.put( prop.getName().getQName().getLocalName(), resolveEntity(prop.getValue())); } return attributeMap; } return null; } private Object resolveEntity(CompiledScript script) { if (script instanceof LiteralScript && String.class.equals(script.getExpectedClass())) { return StringUtil.resolveEntity((String) script.execute(null)); } return script.execute(null); } public ProcessorTreeWalker[] divide(SequenceIDGenerator sequenceIDGenerator) { return new ProcessorTreeWalker[] { this }; } }