📄 bindinggenerator.java
字号:
/*Copyright (c) 2004-2005, 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;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintStream;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import org.apache.bcel.classfile.Field;import org.apache.bcel.classfile.JavaClass;import org.jibx.binding.classes.ClassCache;import org.jibx.binding.classes.ClassFile;import org.jibx.binding.classes.ClassItem;import org.jibx.binding.model.BindingElement;import org.jibx.binding.model.CollectionElement;import org.jibx.binding.model.ContainerElementBase;import org.jibx.binding.model.MappingElement;import org.jibx.binding.model.NamespaceElement;import org.jibx.binding.model.StructureElement;import org.jibx.binding.model.StructureElementBase;import org.jibx.binding.model.ValueElement;import org.jibx.binding.util.ObjectStack;import org.jibx.runtime.BindingDirectory;import org.jibx.runtime.IBindingFactory;import org.jibx.runtime.IMarshallingContext;import org.jibx.runtime.JiBXException;/** * Binding generator. This loads the specified input classes and processes them * to generate a default binding definition. * * @author Dennis M. Sosnoski * @version 1.0 */ public class BindingGenerator{ /** Generator version. */ private static String CURRENT_VERSION = "0.2"; /** Set of objects treated as primitives. */ private static HashSet s_objectPrimitiveSet = new HashSet(); static { s_objectPrimitiveSet.add("java.lang.Boolean"); s_objectPrimitiveSet.add("java.lang.Byte"); s_objectPrimitiveSet.add("java.lang.Char"); s_objectPrimitiveSet.add("java.lang.Double"); s_objectPrimitiveSet.add("java.lang.Float"); s_objectPrimitiveSet.add("java.lang.Integer"); s_objectPrimitiveSet.add("java.lang.Long"); s_objectPrimitiveSet.add("java.lang.Short"); s_objectPrimitiveSet.add("java.math.BigDecimal"); s_objectPrimitiveSet.add("java.math.BigInteger");//#!j2me{ s_objectPrimitiveSet.add("java.sql.Date"); s_objectPrimitiveSet.add("java.sql.Time"); s_objectPrimitiveSet.add("java.sql.Timestamp");//#j2me} s_objectPrimitiveSet.add("java.util.Date"); } /** Show verbose output flag. */ private boolean m_verbose; /** Use camel case for XML names flag. */ private boolean m_mixedCase; /** Namespace URI for elements. */ private String m_namespaceUri; /** Class names to mapped element names map. */ private HashMap m_mappedNames; /** Class names to properties list map. */ private HashMap m_beanNames; /** Class names to deserializers map for typesafe enumerations. */ private HashMap m_enumerationNames; /** Stack of structure definitions in progress (used to detect cycles). */ private ObjectStack m_structureStack; /** Class names bound as nested structures. */ private HashSet m_structureNames; /** Class names to be treated like interfaces (not mapped directly). */ private HashSet m_ignoreNames; /** * Default constructor. This just initializes all options disabled. */ public BindingGenerator() { m_mappedNames = new HashMap(); m_structureStack = new ObjectStack(); m_structureNames = new HashSet(); m_ignoreNames = new HashSet(); } /** * Constructor with settings specified. * * @param verbose report binding details and results * @param mixed use camel case in element names * @param uri namespace URI for element bindings */ public BindingGenerator(boolean verbose, boolean mixed, String uri) { this(); m_verbose = verbose; m_mixedCase = mixed; m_namespaceUri = uri; } /** * Set control flag for verbose processing reports. * * @param verbose report verbose information in processing bindings flag */ public void setVerbose(boolean verbose) { m_verbose = verbose; } /** * Set control flag for camel case element naming. * * @param camel use camel case element naming flag */ public void setCamelCase(boolean camel) { m_mixedCase = camel; } /** * Indent to proper depth for current item. * * @param pw output print stream to be indented */ private void nestingIndent(PrintStream pw) { for (int i = 0; i < m_structureStack.size(); i++) { pw.print(' '); } } /** * Convert class or unprefixed field name to element or attribute name. * * @param base class or simple field name to be converted * @return element or attribute name */ private String convertName(String base) { StringBuffer name = new StringBuffer(); name.append(Character.toLowerCase(base.charAt(0))); if (m_mixedCase) { name.append(base.substring(1)); } else { boolean ignore = true; for (int i = 1; i < base.length(); i++) { char chr = base.charAt(i); if (Character.isUpperCase(chr)) { chr = Character.toLowerCase(chr); if (ignore) { int next = i + 1; ignore = next >= base.length() || Character.isUpperCase(base.charAt(next)); } if (ignore) { name.append(chr); } else { name.append('-'); name.append(chr); ignore = true; } } else { name.append(chr); ignore = false; } } } return name.toString(); } /** * Generate structure element name from class name using set conversions. * * @param cname class name to be converted * @return element name for instances of class */ public String elementName(String cname) { int split = cname.lastIndexOf('.'); if (split >= 0) { cname = cname.substring(split+1); } while ((split = cname.indexOf('$')) >= 0) { cname = cname.substring(0, split) + cname.substring(split+1); } return convertName(cname); } /** * Generate structure element name from class name using set conversions. * * @param fname field name to be converted * @return element name for instances of class */ private String valueName(String fname) { String base = fname; if (base.startsWith("m_")) { base = base.substring(2); } else if (base.startsWith("_")) { base = base.substring(1); } else if (base.startsWith("f") && base.length() > 1) { if (Character.isUpperCase(base.charAt(1))) { base = base.substring(1); } } return convertName(base); } /** * Construct the list of child binding components that define the binding * structure for fields of a particular class. This binds all * non-final/non-static/non-transient fields of the class, if necessary * creating nested structure elements for unmapped classes referenced by the * fields. * * @param cf class information * @param contain binding structure container element * @throws JiBXException on error in binding generation */ private void defineFields(ClassFile cf, ContainerElementBase contain) throws JiBXException { // process all non-final/non-static/non-transient fields of class JavaClass clas = cf.getRawClass(); Field[] fields = clas.getFields(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; if (!field.isFinal() && !field.isStatic() && !field.isTransient()) { // find type of handling needed for field type boolean simple = false; boolean object = true; boolean attribute = true; String fname = field.getName(); String tname = field.getType().toString(); if (ClassItem.isPrimitive(tname)) { simple = true; object = false; } else if (s_objectPrimitiveSet.contains(tname)) { simple = true; } else if (tname.equals("byte[]")) { simple = true; attribute = false; } else if (tname.startsWith("java.")) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -