📄 schemadetaildirectory.java
字号:
/*Copyright (c) 2007, Dennis M. SosnoskiAll rights reserved.Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of JiBX nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FORANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ONANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/package org.jibx.binding.generator;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.Map;import org.jibx.binding.model.BindingElement;import org.jibx.binding.model.CollectionElement;import org.jibx.binding.model.ContainerElementBase;import org.jibx.binding.model.IClass;import org.jibx.binding.model.IClassLocator;import org.jibx.binding.model.IComponent;import org.jibx.binding.model.MappingElement;import org.jibx.binding.model.ModelVisitor;import org.jibx.binding.model.StructureElement;import org.jibx.binding.model.StructureElementBase;import org.jibx.binding.model.TemplateElementBase;import org.jibx.binding.model.ValidationContext;import org.jibx.binding.model.ValueElement;import org.jibx.runtime.QName;import org.jibx.util.Types;/** * Directory for components included in schema generation. This includes both * <mapping> elements of the bindings and special formats, with the latter * currently limited to enumeration types. The building code works from a * supplied list of bindings, walking the tree structure of the bindings to find * all mappings and processing each mapping directly using the lists of child * components. It creates mapping details and sets flags for the types of access * to each mapping, as well as creating enumeration details and counting usage * to select globals. */public class SchemaDetailDirectory{ /** Locator for class information (<code>null</code> if none). */ private final IClassLocator m_locator; /** Binding customization information. */ private final GlobalCustom m_custom; /** Validation context for bindings. */ private final ValidationContext m_context; /** Map from <mapping> definition to mapping detail. */ private final Map m_mappingMap; /** Map from class name to enumeration detail. */ private final Map m_enumMap; /** * Constructor. * * @param loc locator for class information (<code>null</code> if none) * @param custom binding customization information (used for creating names * as needed) * @param vctx binding validation context */ public SchemaDetailDirectory(IClassLocator loc, GlobalCustom custom, ValidationContext vctx) { m_locator = loc; m_custom = custom; m_context = vctx; m_mappingMap = new HashMap(); m_enumMap = new HashMap(); } /** * Populate the mapping directory from a supplied list of root bindings. * This uses a visitor to analyze the bindings, building the detail * information to be used during the actual generation process. * * @param holders */ public void populate(ArrayList holders) { AnalysisVisitor visitor = new AnalysisVisitor(m_context); for (int i = 0; i < holders.size(); i++) { BindingHolder holder = (BindingHolder)holders.get(i); m_context.tourTree(holder.getBinding(), visitor); } } /** * Check if a <structure> element represents a type derivation. If the * element is empty, has no name or property, is required, and is a mapping * reference, then it can be handled as a type derivation. * * @param struct * @return <code>true</code> if a type derivation, <code>false</code> if not */ private static boolean isTypeDerivation(StructureElement struct) { return struct.children().size() == 0 && !struct.hasName() && !struct.hasProperty() && !struct.isOptional() && (struct.getDeclaredType() != null || struct.getEffectiveMapping() != null); } /** * Check if class is an enumeration type. * * @param clas * @return enumeration type flag */ private boolean isEnumeration(IClass clas) { return clas.isSuperclass("java.lang.Enum"); } /** * Check if class is a simple value type. * * @param clas * @return simple value type flag */ private boolean isSimpleValue(IClass clas) { return Types.isSimpleValue(clas.getName()); } /** * Count the usage of an enumeration type. The first time this is called for * a type it just creates the enumeration detail, then if called again for * the same type it flags it as a global. * * @param type */ private void countEnumUsage(String type) { SchemaEnumDetail detail = (SchemaEnumDetail)m_enumMap.get(type); if (detail == null) { ClassCustom custom = m_custom.forceClassCustomization(type); detail = new SchemaEnumDetail(custom); m_enumMap.put(type, detail); } else { detail.setGlobal(true); } } /** * Check references to mappings or enumeration types from component children * of binding container element. This allows the starting offset for content * children to be passed in, so that mappings with type extension components * can be handled (with the extension component processed separately, since * it's a special case). * * @param cont container element * @param offset starting offset for content */ private void checkReferences(ContainerElementBase cont, int offset) { // first process content components of container ArrayList contents = cont.getContentComponents(); for (int i = offset; i < contents.size(); i++) { IComponent comp = (IComponent)contents.get(i); if (comp instanceof ValueElement) { // check value reference to enumeration type IClass type = ((ValueElement)comp).getType(); if (isEnumeration(type)) { countEnumUsage(type.getName()); } } else if (comp instanceof CollectionElement) { // check for collection item type CollectionElement collect = (CollectionElement)comp; IClass itype = collect.getItemTypeClass(); if (isEnumeration(itype)) { // collection items are enumeration type, count directly countEnumUsage(itype.getName()); } else if (!isSimpleValue(itype)) { // find implied mapping, if one defined String type = itype.getName(); TemplateElementBase ref = collect.getDefinitions().getSpecificTemplate(type); if (ref instanceof MappingElement) { MappingElement mapref = (MappingElement)ref; SchemaMappingDetail detail = forceMappingDetail(mapref); detail.setElement(true); } } // check for nested type reference(s) checkReferences(collect, 0); } else { // structure, check for nested definition StructureElement struct = (StructureElement)comp; if (struct.children().size() > 0) { // just handle references from nested components checkReferences(struct, 0); } else { // no nested definition, check for mapping reference MappingElement ref = (MappingElement)struct.getEffectiveMapping(); if (ref == null) { m_context.addError("No handling defined for empty structure with no mapping reference", struct); } else { // get the referenced mapping information SchemaMappingDetail detail = forceMappingDetail(ref); if (struct.getName() == null) { if (ref.isAbstract()) { // abstract inline treated as group detail.setGroup(true); } else { // concrete treated as element reference detail.setElement(true); } } else if (!ref.isAbstract()) { // concrete with name should never happen m_context.addError("No handling defined for name on concrete mapping reference", struct); } } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -