首页>代码>深入浅出hibernate书籍的源代码下载>/深入浅出Hibernate源码/samples-dist/tools/ext-tools/src/java/net/sf/hibernate/tool/hbm2java/BasicRenderer.java
//$Id: BasicRenderer.java,v 1.16.2.4 2004/05/24 19:04:10 maxcsaucdk Exp $
package net.sf.hibernate.tool.hbm2java;

import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.hibernate.util.StringHelper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class BasicRenderer extends AbstractRenderer {
	
	static final protected int ORDINARY = 0;
	static final protected int BOUND = 1;
	static final protected int CONSTRAINT = 3;//any constraint properties are bound as well

	private static Log log = LogFactory.getLog(BasicRenderer.class);
	JavaTool javaTool = new JavaTool();
	
 	public void render(String savedToPackage, String savedToClass, ClassMapping classMapping, Map class2classmap, PrintWriter mainwriter) throws Exception {
 		
 		
        genPackageDelaration(savedToPackage, classMapping, mainwriter);
        mainwriter.println();
    
        // switch to another writer to be able to insert the actually
        // used imports when whole class has been rendered. 
        StringWriter strWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(strWriter);
        
    
        // class declaration
        if(classMapping.getMeta("class-description")==null) {
            writer.println("/** @author Hibernate CodeGenerator */");
        } else {
            writer.println("/** \n" + javaTool.toJavaDoc(classMapping.getMetaAsString("class-description"),0)  + "*/");   
        }
        
        String classScope = classMapping.getScope();
        String declarationType = classMapping.getDeclarationType();
        

        classMapping.addImport(Serializable.class);
        //String modifiers = classMapping.getModifiers();
        if(classMapping.shouldBeAbstract() && (classScope.indexOf("abstract")==-1)) {
            writer.print( "abstract " + classScope + " " + declarationType + " " + savedToClass );
        } else {
            writer.print( classScope +  " " + declarationType + " " + savedToClass );    
        }
    
        if(generateConcreteEmptyClasses()) {
        	writer.print(" extends " + getProperty("baseclass-prefix","Base") + classMapping.getName());
        } else {
        	if(javaTool.hasExtends(classMapping)) {
        		writer.print(" extends " + javaTool.getExtends(classMapping));
        	}
        }
        
		if(javaTool.hasImplements(classMapping)) {
			writer.print(" implements " + javaTool.getImplements(classMapping));
		}
        
        writer.println(" {");
        writer.println();
        
        // switch to another writer to be able to insert the 
        // veto- and changeSupport fields
        StringWriter strPropWriter = new StringWriter();
        PrintWriter propWriter = new PrintWriter(strPropWriter);

        String vetoSupport = null, changeSupport = null;
        int fieldTypes = 0;
        
        if(!generateConcreteEmptyClasses()) {
        	if(!classMapping.isInterface()) {
        		/*doFieldNameConstants(classMapping, propWriter);*/
        		doFields(classMapping, class2classmap, propWriter);
        		doConstructors(savedToClass, classMapping, class2classmap, propWriter);
        	}
        	
        	vetoSupport = makeSupportField("vetos", classMapping.getAllFields());
        	changeSupport = makeSupportField("changes", classMapping.getAllFields());    
        	fieldTypes = doFieldAccessors(classMapping, class2classmap, propWriter, vetoSupport, changeSupport);
        	
        	if(!classMapping.isInterface()) {
        		doSupportMethods(fieldTypes, vetoSupport, changeSupport, propWriter);
        		
        		doToString(classMapping, propWriter);
        		
        		doEqualsAndHashCode(savedToClass,classMapping, propWriter);
        		
        	}
        	if(classMapping.getMeta("class-code")!=null) {
        		propWriter.println("// The following is extra code specified in the hbm.xml files");
        		List extras = classMapping.getMeta("class-code");
        		Iterator iter = extras.iterator();
        		while (iter.hasNext()) {
        			String code = iter.next().toString();
        			propWriter.println(code);	
        		}
        		
        		propWriter.println("// end of extra code specified in the hbm.xml files");
        	}
        } else {
        	// only put in constructors when base-generation is active
        	doConstructors(savedToClass, classMapping, class2classmap, propWriter);
        }
        
     	propWriter.println("}");
	      
        //insert change and VetoSupport
        if(!classMapping.isInterface() && generateConcreteEmptyClasses()) {
        	doSupports(fieldTypes, classMapping, vetoSupport, changeSupport, writer);
        }
        
        writer.print(strPropWriter.toString());
        
        
        // finally write the imports
        doImports(classMapping, mainwriter);
        mainwriter.print(strWriter.toString());
        
        
    }

	private String getProperty(String key, String defaultValue) {
		return properties.getProperty(key, defaultValue);
	}

	/**
	 * Method doSupportMethods.
	 * @param fieldTypes
	 * @param vetoSupport
	 * @param changeSupport
	 * @param propWriter
	 */
	private void doSupportMethods(
		int fieldTypes,
		String vetoSupport,
		String changeSupport,
		PrintWriter writer) {
			if((fieldTypes&CONSTRAINT)==CONSTRAINT) {
				writer.println("    public void addVetoableChangeListener( VetoableChangeListener l ) {");
				writer.println("        "+vetoSupport+".addVetoableChangeListener(l);");
				writer.println("    }");
				writer.println("    public void removeVetoableChangeListener( VetoableChangeListener l ) {");
				writer.println("        "+vetoSupport+".removeVetoableChangeListener(l);");
				writer.println("    }");
				writer.println();
			}
			if((fieldTypes&BOUND)==BOUND) {
				writer.println("    public void addPropertyChangeListener( PropertyChangeListener l ) {");
				writer.println("        "+changeSupport+".addPropertyChangeListener(l);");
				writer.println("    }");
				writer.println("    public void removePropertyChangeListener( PropertyChangeListener l ) {");
				writer.println("        "+changeSupport+".removePropertyChangeListener(l);");
				writer.println("    }");
				writer.println();
			}
	}


	/**
	 * Method doSupports.
	 * @param vetoSupport
	 * @param changeSupport
	 * @param writer
	 */
	private void doSupports( int fieldTypes, 
											ClassMapping classMapping,
											String vetoSupport,
											String changeSupport,
											PrintWriter writer) {
			if((fieldTypes&CONSTRAINT)==CONSTRAINT) {
				writer.println( "    private VetoableChangeSupport "+vetoSupport+
					" = new VetoableChangeSupport(this);" );
				classMapping.getImports().add("java.beans.VetoableChangeSupport");
				classMapping.getImports().add("java.beans.PropertyVetoException");
				classMapping.getImports().add("java.beans.VetoableChangeListener");
			}
			if((fieldTypes&BOUND)==BOUND) {
				writer.println( "    private PropertyChangeSupport "+changeSupport+
					" = new PropertyChangeSupport(this);" );
				writer.println();
				classMapping.getImports().add("java.beans.PropertyChangeSupport");
				classMapping.getImports().add("java.beans.PropertyChangeListener");
			}
	}


	public void doConstructors(String savedToClass, ClassMapping classMapping, Map class2classmap, PrintWriter writer) {
		// full constructor
		List allFieldsForFullConstructor = classMapping.getAllFieldsForFullConstructor();
		
		writer.println("    /** full constructor */");
		String fullCons = "    public " + savedToClass + StringHelper.OPEN_PAREN;
		
		fullCons += javaTool.fieldsAsParameters(allFieldsForFullConstructor, classMapping, class2classmap);
		
		writer.println(fullCons + ") {");
		
		if(!generateConcreteEmptyClasses()) {
			//invoke super to initialize superclass...
			List supersConstructorFields = classMapping.getFieldsForSupersFullConstructor();
			if (!supersConstructorFields.isEmpty()) {
				writer.print("        super(");
				for (Iterator fields = supersConstructorFields.iterator(); fields.hasNext();) {
					FieldProperty field = (FieldProperty) fields.next();
					writer.print(field.getFieldName());
					if(fields.hasNext()) {
						writer.print(", ");
					}
				}
				writer.println(");");
			}
			
			// initialisation of localfields
			for(Iterator fields = classMapping.getLocalFieldsForFullConstructor().iterator(); fields.hasNext();) {
				FieldProperty field = (FieldProperty) fields.next();
				if(field.isGeneratedAsProperty()) {
					writer.println("        this." + field.getFieldName() + " = " + field.getFieldName() + ";");
				}
			}
		} else {
			// invoke base class constructor 
			List supersConstructorFields = classMapping.getAllFieldsForFullConstructor();
			if (!supersConstructorFields.isEmpty()) {
				writer.print("        super(");
				for (Iterator fields = supersConstructorFields.iterator(); fields.hasNext();) {
					FieldProperty field = (FieldProperty) fields.next();
					writer.print(field.getFieldName());
					if(fields.hasNext()) {
						writer.print(", ");
					}
				}
				writer.println(");");
			}
		}
		
		writer.println("    }");
		writer.println();
		
		// no args constructor (if fullconstructor had any arguments!)
		if (allFieldsForFullConstructor.size() > 0) {
		    writer.println("    /** default constructor */");
			writer.println("    public " + savedToClass + "() {");
			writer.println("    }");
			writer.println();
		}
		
		// minimal constructor (only if the fullconstructor had any arguments)
		if ((allFieldsForFullConstructor.size() > 0) && classMapping.needsMinimalConstructor()) {
		
		    List allFieldsForMinimalConstructor = classMapping.getAllFieldsForMinimalConstructor();
		    writer.println("    /** minimal constructor */"); 
		
		    String minCons = "    public " + savedToClass + "(";
		    for (Iterator fields = allFieldsForMinimalConstructor.iterator(); fields.hasNext();) {
		        FieldProperty field = (FieldProperty) fields.next();
		        minCons = minCons + JavaTool.shortenType(JavaTool.getTrueTypeName(field, class2classmap), classMapping.getImports()) + " " + field.getFieldName();
		        if (fields.hasNext()) {
		            minCons = minCons + ", ";
		        }
		    }
		
		    writer.println(minCons + ") {");
		    if(!generateConcreteEmptyClasses()) {
		    	// invoke super to initialize superclass...
		    	List supersMinConstructorFields = classMapping.getFieldsForSupersMinimalConstructor();
		    	if (!supersMinConstructorFields.isEmpty()) {
		    		writer.print("      super(");
		    		for (Iterator fields = supersMinConstructorFields.iterator(); fields.hasNext();) {
		    			FieldProperty field = (FieldProperty) fields.next();
		    			writer.print(field.getFieldName());
		    			if(fields.hasNext()) {
		    				writer.print(StringHelper.COMMA_SPACE);
		    			}
		    		}
		    		writer.println(");");
		    	}
		    	
		    	// initialisation of localfields
		    	for (Iterator fields = classMapping.getLocalFieldsForMinimalConstructor().iterator(); fields.hasNext();) {
		    		FieldProperty field = (FieldProperty) fields.next();
		    		if(field.isGeneratedAsProperty()) {
		    			writer.println("        this." + field.getFieldName() + " = " + field.getFieldName() + ";");
		    		}
		    	}
		    } else {
		    	List supersMinConstructorFields = classMapping.getAllFieldsForMinimalConstructor();
			    if (!supersMinConstructorFields.isEmpty()) {
			    	writer.print("      super(");
			    	for (Iterator fields = supersMinConstructorFields.iterator(); fields.hasNext();) {
			    		FieldProperty field = (FieldProperty) fields.next();
			    		writer.print(field.getFieldName());
			    		if(fields.hasNext()) {
			    			writer.print(StringHelper.COMMA_SPACE);
			    		}
			    	}
			    	writer.println(");");
			    }			    	
		    }
		    writer.println("    }");
		    writer.println();
		}
	}

   /* public void doFieldNameConstants(ClassMapping classMapping, PrintWriter writer) {
        // fields
        for ( Iterator fields = classMapping.getFields().iterator(); fields.hasNext(); ) {
            FieldProperty field = (FieldProperty) fields.next();

            if(field.isGeneratedAsProperty()) {
                String fieldName = "    "+"public static String FIELD_"+field.getFieldName().toUpperCase()
                    +" = \""+classMapping.getFullyQualifiedName()+"."+field.getFieldName()+"\";";
                writer.println(fieldName);
            }
        }
        writer.println();
    }*/


	private boolean generateConcreteEmptyClasses() {
		return isPropertySet("generate-concrete-empty-classes");
	}

	public void doFields(ClassMapping classMapping, Map class2classmap, PrintWriter writer) {
		// fields
		if(!classMapping.isInterface()) {
			if(classMapping.isSuperInterface()) {
				doFields(classMapping.getAllFields(), classMapping.getImports(), class2classmap, writer); 
			}
		}
		List fieldList = classMapping.getFields();
		Set imports = classMapping.getImports();
		doFields(fieldList, imports, class2classmap, writer);
	}

	private void doFields(List fieldList, Set imports, Map class2classmap, PrintWriter writer) {
		for ( Iterator fields = fieldList.iterator(); fields.hasNext(); ) {
		    FieldProperty field = (FieldProperty) fields.next();
		    
		    if(field.isGeneratedAsProperty()) {
		    String fieldScope = getFieldScope(field, "scope-field", "private");
		    writer.println( 
		    	"    /** " + 
		    	( field.isNullable() && !field.isIdentifier() ? "nullable " : StringHelper.EMPTY_STRING ) +
		    	( field.isIdentifier() ? "identifier" : "persistent" )
		    	+ " field */");
		    
			writer.print(
		    	"    " + fieldScope + " " + 
		    	JavaTool.shortenType( JavaTool.getTrueTypeName(field, class2classmap), imports ) + 
		    	' ' + 
		    	field.getFieldName());
                
            if(field.getMeta("default-value")!=null) {
                writer.print(" = " + field.getMetaAsString("default-value"));
            }
            writer.println(';');
		    }
			writer.println();
		}
	}

	public void doEqualsAndHashCode(String savedToClass, ClassMapping classMapping, PrintWriter writer) {
		if(classMapping.getSuperClassMapping()!=null) {
			for (Iterator fields = classMapping.getFields().iterator(); fields.hasNext();) {
				FieldProperty field = (FieldProperty) fields.next();
				if(field.getMetaAsBool("use-in-equals")) {
					log.warn("use-in-equals for property " + field.getFieldName() + " in " + classMapping.getName() + " will be ignored since it is in a subclass.  \"There is simply no way to extend an instantiable class and add an aspect while preserving the equals() contract\" -- Bloch.");
				}
			}			
		} else {
			if ( classMapping.mustImplementEquals() ) {
				classMapping.getImports().add("org.apache.commons.lang.builder.EqualsBuilder");
				classMapping.getImports().add("org.apache.commons.lang.builder.HashCodeBuilder");
				writer.println("    public boolean equals(Object other) {");
				writer.println("        if ( (this == other ) ) return true;"); // == identity
				writer.println("        if ( !(other instanceof " + savedToClass + ") ) return false;"); // same class ?
				writer.println("        " + savedToClass + " castOther = (" + savedToClass + ") other;"); 
				writer.println("        return new EqualsBuilder()");
				int usedFields = 0;
				List idFields = new ArrayList();
				for (Iterator fields = classMapping.getAllFields().iterator(); fields.hasNext();) {
					FieldProperty field = (FieldProperty) fields.next();
					if(field.getMetaAsBool("use-in-equals")) {
						writer.println("            .append(this." + field.getGetterSignature() + ", castOther." + field.getGetterSignature() + StringHelper.CLOSE_PAREN);		    									
						usedFields++;
					}
					if(field.isIdentifier()) {
						idFields.add(field);
					}		    		
				}
				if(usedFields==0) {
					log.warn("No properties has been marked as being used in equals/hashcode for " + classMapping.getName() + ". Using object identifier which is RARELY safe to use! See http://hibernate.org/109.html");
					for (Iterator fields = idFields.iterator(); fields.hasNext();) {
						FieldProperty field = (FieldProperty) fields.next();
						writer.println("            .append(this." + field.getGetterSignature() + ", castOther." + field.getGetterSignature() + StringHelper.CLOSE_PAREN);
					}		    		
				}
				writer.println("            .isEquals();");
				
				writer.println("    }");
				writer.println();
				
				writer.println("    public int hashCode() {");
				writer.println("        return new HashCodeBuilder()");
				
				for (Iterator fields = classMapping.getAllFields().iterator(); fields.hasNext();) {
					FieldProperty field = (FieldProperty) fields.next();
					if(field.getMetaAsBool("use-in-equals")) {
						writer.println("            .append(" + field.getGetterSignature() + StringHelper.CLOSE_PAREN);
					}
				}
				if(usedFields==0) {
					for (Iterator fields = idFields.iterator(); fields.hasNext();) {
						FieldProperty field = (FieldProperty) fields.next();
						writer.println("            .append(" + field.getGetterSignature() + StringHelper.CLOSE_PAREN);
					}		    		
				}
				
				writer.println("            .toHashCode();");
				writer.println("    }");
				writer.println();
			}
		}
	}

	public void doToString(ClassMapping classMapping, PrintWriter writer) {
		if(classMapping.getMetaAsBool("implement-tostring",true)) {
		classMapping.addImport("org.apache.commons.lang.builder.ToStringBuilder");	
		writer.println("    public String toString() {");
		writer.println("        return new ToStringBuilder(this)");
		for (Iterator fields = classMapping.getAllFields().iterator(); fields.hasNext();) {
			FieldProperty field = (FieldProperty) fields.next();
			// If nothing is stated about id then include it in toString()
			if(field.isIdentifier() && field.getMeta("use-in-tostring")==null) {
				writer.println("            .append(\"" + field.getFieldName() + "\", " + field.getGetterSignature() + ")");
			} else if(field.getMetaAsBool("use-in-tostring")) {
				writer.println("            .append(\"" + field.getFieldName() + "\", " + field.getGetterSignature() + ")");
			}
		}
		writer.println("            .toString();");
		writer.println("    }");
		writer.println();
		}
	}
	
	static Map primitiveToObject = new HashMap();
	{
	  primitiveToObject.put("char", "Character");
	  
	  primitiveToObject.put("byte", "Byte");
	  primitiveToObject.put("short", "Short");
	  primitiveToObject.put("int",  "Integer");
	  primitiveToObject.put("long", "Long");
	  
	  primitiveToObject.put("boolean", "Boolean");
	  
	  primitiveToObject.put("float", "Float");
	  primitiveToObject.put("double", "Double");
	    	
	}
	
    public int doFieldAccessors(ClassMapping classMapping, 
    											Map class2classmap, 
    											PrintWriter writer,
    											String vetoSupport,
    											String changeSupport) {
    	int fieldTypes=ORDINARY;
    	
    	if(classMapping.isSuperInterface()) {
    		fieldTypes = doFields(classMapping, class2classmap, writer, vetoSupport, changeSupport, fieldTypes, classMapping.getAllFields());
    	}
    	List fieldz = classMapping.getFields();
        fieldTypes = doFields(classMapping, class2classmap, writer, vetoSupport, changeSupport, fieldTypes, fieldz);
        return fieldTypes;
        
    }

    private int doFields(ClassMapping classMapping, Map class2classmap, PrintWriter writer, String vetoSupport, String changeSupport, int fieldTypes, List fieldz) {
		// field accessors
        for (Iterator fields = fieldz.iterator(); fields.hasNext();) {
            FieldProperty field = (FieldProperty) fields.next();
            if(field.isGeneratedAsProperty()) {
        
            // getter
            String getAccessScope = getFieldScope(field, "scope-get", "public");
            
        
            if(field.getMeta("field-description")!=null) {
            writer.println("    /** \n" + javaTool.toJavaDoc(field.getMetaAsString("field-description"), 4) + "     */"); 
            }
            writer.print("    " + getAccessScope + " " + JavaTool.shortenType(JavaTool.getTrueTypeName(field, class2classmap),classMapping.getImports()) + " " + field.getGetterSignature());
 			if(classMapping.isInterface()) {
				writer.println(";");
 			} else {
				writer.println(" {");
			    writer.println("        return this." + field.getFieldName() + ";");
            	writer.println("    }");
			}
            writer.println();
        
            // setter
            int fieldType=0;
            if(field.getMeta("beans-property-type")!=null) {
            	String beansPropertyType = field.getMetaAsString("beans-property-type").trim().toLowerCase();
            	if(beansPropertyType.equals("constraint") ) {
            		fieldTypes = (fieldTypes | CONSTRAINT);
            		fieldType = CONSTRAINT;
            	}
            	else if(beansPropertyType.equals("bound") ) {
            		fieldTypes = (fieldTypes | BOUND);
            		fieldType = BOUND;
            	}
            }
            String setAccessScope = getFieldScope(field, "scope-set", "public");
            writer.print("    " + setAccessScope + " void set" + field.getAccessorName() + StringHelper.OPEN_PAREN + JavaTool.shortenType(JavaTool.getTrueTypeName(field, class2classmap),classMapping.getImports()) + " " + field.getFieldName() + ")");
            writer.print((fieldType&CONSTRAINT)==CONSTRAINT ? " throws PropertyVetoException ":"");
            if(classMapping.isInterface()) {
            	writer.println(";");
            } else {
				writer.println(" {");
				if((fieldType&CONSTRAINT)==CONSTRAINT || (fieldType&BOUND)==BOUND) {
					writer.println("        Object oldValue = "+getFieldAsObject(true, field)+";");
				}
				if((fieldType&CONSTRAINT)==CONSTRAINT) {
						
            			writer.println("        "+vetoSupport+".fireVetoableChange(\""+field.getFieldName()+"\",");
					    writer.println("                oldValue,");
            			writer.println("                "+getFieldAsObject(false, field)+");");
				}
				
            	writer.println("        this." + field.getFieldName() + " = " + field.getFieldName() + ";");
            	if((fieldType&BOUND)==BOUND) {
            			writer.println("        "+changeSupport+".firePropertyChange(\""+field.getFieldName()+"\",");
            			writer.println("                oldValue,");
            			writer.println("                "+getFieldAsObject(false, field)+");");
            	}
            	writer.println("    }");
            }
            writer.println();
            
            // add/remove'rs (commented out for now)
            /* 
            if(field.getForeignClass()!=null) { 
                ClassName foreignClass = field.getForeignClass();
                
                String trueforeign = getTrueTypeName(foreignClass, class2classmap);
                classMapping.addImport(trueforeign);
                
                // Try to identify the matching set method on the child.
                ClassMapping forignMap = (ClassMapping) class2classmap.get(foreignClass.getFullyQualifiedName());
                
                if(forignMap!=null) {
                  Iterator foreignFields = forignMap.getFields().iterator();
                  while (foreignFields.hasNext()) {
                    Field ffield = (Field) foreignFields.next();
                    if(ffield.isIdentifier()) {
                       log.debug("Trying to match " + ffield.getName() + " with " + field.getForeignKeys());   
                    }
                }
                  
                } else {
                  log.error("Could not find foreign class's mapping - cannot provide bidirectional setters!");   
                }
                
                String addAccessScope = getFieldScope(field, "scope", "scope-add");
                writer.println("    " + setAccessScope + " void add" + field.getAsSuffix() + StringHelper.OPEN + shortenType(trueforeign, classMapping.getImports()) + " a" + field.getName() + ") {");
                writer.println("        this." + getterType + field.getAsSuffix() + "().add(a" + field.getName() + ");");
                writer.println("        a" + field.getName() + ".setXXX(this);");
                writer.println("    }");
                writer.println();
            
            
            }
            */
        }
        }
		return fieldTypes;
	}

	public void doImports(ClassMapping classMapping, PrintWriter writer) {
            writer.println(javaTool.genImports(classMapping));
            writer.println();
    }
    
    protected String makeSupportField(String fieldName, List fieldList) {
		String suffix = "";
		boolean needSuffix = false;
		for (Iterator fields = fieldList.iterator(); fields.hasNext();) {
			String name = ((FieldProperty) fields.next()).getFieldName();
			if (name.equals(fieldName))
				needSuffix = true;
			suffix += name;
		}
		return needSuffix ? fieldName + "_" + suffix : fieldName;
	}
	
	private String getFieldAsObject(boolean prependThis, FieldProperty field) {
				ClassName type = field.getClassType();			
				if(type != null && type.isPrimitive() && !type.isArray()) {
						String typeName = (String) primitiveToObject.get(type.getName());
						typeName = "new "+typeName+"( ";
						typeName += prependThis ? "this." : "";
						return typeName+field.getFieldName()+" )";        			
				}
				return (prependThis?"this.":"")+field.getFieldName(); 
		}

	boolean isPropertySet(String key) {
		String val = properties.getProperty(key);
		return Boolean.valueOf(val).booleanValue();
	}	
}
最近下载更多
shancjb  LV1 2020年5月25日
oaggao  LV1 2020年2月7日
qq893051835  LV1 2019年9月13日
ytx012  LV1 2019年7月11日
Zionism  LV6 2019年5月5日
DevLegal  LV2 2018年10月15日
lianghao1  LV1 2018年10月13日
张兆生  LV26 2018年7月25日
adminsht  LV2 2017年9月6日
dagf113225  LV68 2017年3月24日
最近浏览更多
liang85  LV1 2023年6月30日
moomin709  LV24 2022年3月29日
无敌是都么寂寞 2021年11月15日
暂无贡献等级
blueskyroof  LV9 2021年1月12日
那一年你在哪  LV13 2020年12月26日
shancjb  LV1 2020年5月25日
zxmiii  LV3 2020年4月18日
pmj2510  LV10 2020年4月16日
陈小弟  LV2 2020年3月27日
张言昊  LV9 2020年3月12日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友