/* * 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.builder; import java.util.Iterator; import org.seasar.mayaa.builder.PathAdjuster; import org.seasar.mayaa.builder.SequenceIDGenerator; import org.seasar.mayaa.builder.library.LibraryManager; import org.seasar.mayaa.cycle.ServiceCycle; import org.seasar.mayaa.cycle.scope.ApplicationScope; import org.seasar.mayaa.engine.processor.TemplateProcessor; import org.seasar.mayaa.engine.specification.Namespace; import org.seasar.mayaa.engine.specification.NodeAttribute; import org.seasar.mayaa.engine.specification.NodeTreeWalker; 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.CONST_IMPL; import org.seasar.mayaa.impl.cycle.CycleUtil; import org.seasar.mayaa.impl.engine.EngineUtil; import org.seasar.mayaa.impl.engine.processor.TemplateProcessorSupport; import org.seasar.mayaa.impl.engine.specification.SpecificationUtil; import org.seasar.mayaa.impl.provider.ProviderUtil; import org.seasar.mayaa.impl.util.StringUtil; /** * @author Masataka Kurihara (Gluegent, Inc.) */ public class BuilderUtil implements CONST_IMPL { private BuilderUtil() { // no instantiation. } public static SpecificationNode createInjectedNode(QName qName, URI uri, SpecificationNode original, boolean mayaa) { if (qName == null || original == null) { throw new IllegalArgumentException(); } String systemID = original.getSystemID(); int lineNumber = original.getLineNumber(); boolean onTemplate = original.isOnTemplate(); int sequenceID = original.getSequenceID(); SpecificationNode node = SpecificationUtil.createSpecificationNode( qName, systemID, lineNumber, onTemplate, sequenceID); if (StringUtil.hasValue(uri)) { PathAdjuster adjuster = ProviderUtil.getPathAdjuster(); boolean needAdjust = adjuster.isTargetNode(original.getQName()); String basePath = null; if (needAdjust) { String contextPath = CycleUtil.getRequestScope().getContextPath(); String sourcePath = EngineUtil.getSourcePath(original); basePath = contextPath + sourcePath; } for (Iterator it = original.iterateAttribute(); it.hasNext();) { NodeAttribute attr = (NodeAttribute) it.next(); String attrValue = attr.getValue(); if (needAdjust && adjuster.isTargetAttribute( original.getQName(), attr.getQName())) { attrValue = adjuster.adjustRelativePath(basePath, attrValue); } String originalName = null; if (StringUtil.isEmpty(attr.getPrefix()) == false && attr.getQName().getLocalName().indexOf(':') < 0) { originalName = attr.getPrefix() + ":" + attr.getQName().getLocalName(); } node.addAttribute(attr.getQName(), originalName, attrValue); } for (Iterator it = original.iteratePrefixMapping(false); it.hasNext();) { PrefixMapping prefixMapping = (PrefixMapping) it.next(); node.addPrefixMapping( prefixMapping.getPrefix(), prefixMapping.getNamespaceURI()); } } //node.setParentSpace(SpecificationUtil.getFixedNamespace(original.getParentSpace())); node.setParentSpace(original.getParentSpace()); node.setDefaultNamespaceURI(original.getDefaultNamespaceURI()); return node; } /** * 指定したsystemIDからmimeTypeを見て、HTMLならHTML用のデフォルトPrefixMappingを、 * それ以外ならXMLのデフォルトPrefixMappingを返します。 * * @param systemID mime-typeを調べるsystemID * @return 適切なデフォルトPrefixMapping */ static PrefixMapping getPrefixMapping(String systemID) { if (systemID != null) { ServiceCycle cycle = CycleUtil.getServiceCycle(); ApplicationScope application = cycle.getApplicationScope(); String mimeType = application.getMimeType(systemID); if (mimeType != null) { if (mimeType.indexOf("xhtml") != -1) { return SpecificationUtil.XHTML_DEFAULT_PREFIX_MAPPING; } else if (mimeType.indexOf("html") != -1) { return SpecificationUtil.HTML_DEFAULT_PREFIX_MAPPING; } } } return SpecificationUtil.XML_DEFAULT_PREFIX_MAPPING; } /** * 現在ServiceCycleからmimeTypeを見て、HTMLならHTML用のデフォルトPrefixMappingを、 * それ以外ならXMLのデフォルトPrefixMappingを返します。 * * @return 適切なデフォルトPrefixMapping */ static PrefixMapping getDefaultPrefixMapping() { NodeTreeWalker original = CycleUtil.getServiceCycle().getOriginalNode(); return getPrefixMapping(original == null ? null : original.getSystemID()); } public static PrefixAwareName parseName( Namespace namespace, String qName) { String[] parsed = qName.split(":"); String prefix = null; String localName = null; URI namespaceURI = null; PrefixMapping mapping = null; if (parsed.length == 2) { prefix = parsed[0]; localName = parsed[1]; mapping = namespace.getMappingFromPrefix(prefix, true); if (mapping == null) { if ("xml".equals(prefix)) { mapping = SpecificationUtil.XML_DEFAULT_PREFIX_MAPPING; } else { // HTA:Applicationのような無作法なものもあるので対応できるようにする。 mapping = getDefaultPrefixMapping(); localName = qName; // プレフィクスも含めて要素名扱いとする。 prefix = ""; } } namespaceURI = mapping.getNamespaceURI(); } else if (parsed.length == 1) { localName = parsed[0]; namespaceURI = namespace.getDefaultNamespaceURI(); if (namespaceURI == null) { mapping = namespace.getMappingFromPrefix("", true); if (mapping == null) { mapping = getDefaultPrefixMapping(); } namespaceURI = mapping.getNamespaceURI(); } } else { throw new IllegalNameException(qName); } if (mapping != null) { prefix = mapping.getPrefix(); } else { prefix = ""; } PrefixAwareName ret = SpecificationUtil.createPrefixAwareName( SpecificationUtil.createQName(namespaceURI, localName), prefix); return ret; } static SpecificationNode nodeCopyOf(SpecificationNode node, QName newQName, SequenceIDGenerator sequenceIDGenerator) { if (newQName == null) { newQName = node.getQName(); } return SpecificationUtil.createSpecificationNode(newQName, node.getSystemID(), node.getLineNumber(), true, sequenceIDGenerator.nextSequenceID()); } public static void characterProcessorCopy(TemplateProcessor from, TemplateProcessorSupport to, SequenceIDGenerator idGenerator) { to.setOriginalNode(from.getOriginalNode()); to.setInjectedNode(from.getInjectedNode()); to.setEvalBodyInclude(false); LibraryManager libraryManager = ProviderUtil.getLibraryManager(); to.setProcessorDefinition( libraryManager.getProcessorDefinition(CONST_IMPL.QM_CHARACTERS)); } }