📄 objectbinding.java
字号:
* each use of that binding. * * @param contain binding definition component containing copy */ public ObjectBinding(IContainer contain, ObjectBinding base) { m_container = contain; m_class = base.m_class; m_factoryMethod = base.m_factoryMethod; m_preSetMethod = base.m_preSetMethod; m_postSetMethod = base.m_postSetMethod; m_preGetMethod = base.m_preGetMethod; m_newInstanceMethod = base.m_newInstanceMethod; m_unmarshalSignature = base.m_unmarshalSignature; m_unmarshalAttributeName = base.m_unmarshalAttributeName; m_unmarshalContentName = base.m_unmarshalContentName; m_isStaticUnmarshal = base.m_isStaticUnmarshal; m_isStaticMarshal = base.m_isStaticMarshal; m_marshalSignature = base.m_marshalSignature; m_marshalAttributeName = base.m_marshalAttributeName; m_marshalContentName = base.m_marshalAttributeName; m_marshalContentName = base.m_marshalContentName; m_unmarshalAttributeMethod = base.m_unmarshalAttributeMethod; m_unmarshalContentMethod = base.m_unmarshalContentMethod; m_marshalAttributeMethod = base.m_marshalAttributeMethod; m_marshalContentMethod = base.m_marshalContentMethod; m_createClass = base.m_createClass; m_idChild = base.m_idChild; m_component = base.m_component; } /** * Generate code for calling a user supplied method. The object methods * support three signature variations, with no parameters, with the * marshalling or unmarshalling context, or with the owning object. * * @param in flag for unmarshalling method * @param method information for method being called * @param mb method builder for generated code */ private void genUserMethodCall(boolean in, ClassItem method, ContextMethodBuilder mb) { // load object reference for virtual call if (!method.isStatic()) { mb.loadObject(); } // check if parameter required for call if (method.getArgumentCount() > 0) { // generate code to load context, then get containing object if // needed for call mb.loadContext(); String type = method.getArgumentType(0); if ("java.lang.Object".equals(type)) { String name = in ? UNMARSHAL_GETSTACKTOPMETHOD : MARSHAL_GETSTACKTOPMETHOD; mb.appendCallVirtual(name, GETSTACKTOP_SIGNATURE); } } // generate appropriate form of call to user method mb.appendCall(method); mb.addMethodExceptions(method); } /** * Generate code to create an instance of the object for this mapping. This * convenience method generates the actual code for creating an instance of * an object. The generated code leaves the created object reference on the * stack. * * @param mb method builder * @throws JiBXException if error in generating code */ private void genNewInstanceCode(ContextMethodBuilder mb) throws JiBXException { // check for factory supplied to create instance if (m_factoryMethod == null) { if (m_createClass.isArray()) { // construct array instance directly with basic size mb.appendLoadConstant(Utility.MINIMUM_GROWN_ARRAY_SIZE); String type = m_createClass.getName(); mb.appendCreateArray(type.substring(0, type.length()-2)); } else { // make sure we have a no argument constructor ClassItem cons = m_createClass.getInitializerMethod("()V"); if (cons == null) { m_createClass.addDefaultConstructor(); } else { cons.makeAccessible(m_class.getMungedFile()); } // no factory, so create an instance, duplicate the // reference, and then call the null constructor mb.appendCreateNew(m_createClass.getName()); mb.appendDUP(); mb.appendCallInit(m_createClass.getName(),"()V"); } } else { // generate call to factory method genUserMethodCall(true, m_factoryMethod, mb); mb.appendCreateCast(m_factoryMethod.getTypeName(), m_class.getClassName()); } } /** * Generate call to new instance creation method for object. This * convenience method just generates code to call the generated new * instance method added to the class definition. * * @param mb method builder * @throws JiBXException if error in configuration */ private void genNewInstanceCall(ContextMethodBuilder mb) throws JiBXException { // check if new instance method needs to be added to class if (m_newInstanceMethod == null) { // set up for constructing new method String name = m_container.getBindingRoot().getPrefix() + NEWINSTANCE_SUFFIX; String sig = UNMARSHAL_PARAMETER_SIGNATURE + m_class.getClassFile().getSignature(); ClassFile cf = m_class.getMungedFile(); ContextMethodBuilder meth = new ContextMethodBuilder(name, sig, cf, Constants.ACC_PUBLIC|Constants.ACC_STATIC, -1, m_class.getClassName(), 0, UNMARSHALLING_CONTEXT); // generate the code to build a new instance genNewInstanceCode(meth); // finish method code with return of new instance meth.appendReturn(m_class.getClassName()); m_newInstanceMethod = m_class.getUniqueMethod(meth).getItem(); } // generate code to call created new instance method mb.loadContext(UNMARSHALLING_CONTEXT); mb.appendCall(m_newInstanceMethod); } /** * Generate code to handle unmarshal source location tracking. This * convenience method generates the member variables and method used to * support setting the source location, the methods used to access the * information, and also adds the appropriate interfaces to the class. * * @throws JiBXException if error in generating code */ private void genTrackSourceCode() throws JiBXException { ClassFile cf = m_class.getMungedFile(); if (!m_isThisBinding && m_class.isDirectAccess() && !cf.isAbstract() && cf.addInterface(SOURCE_TRACKING_INTERFACE)) { // add position tracking fields to class ClassItem srcname = cf.addPrivateField("java.lang.String;", SOURCEDOCUMENT_FIELDNAME); ClassItem srcline = cf.addPrivateField("int", SOURCELINE_FIELDNAME); ClassItem srccol = cf.addPrivateField("int", SOURCECOLUMN_FIELDNAME); // add method for setting the source information MethodBuilder mb = new ExceptionMethodBuilder(SETSOURCE_METHODNAME, Type.VOID, SETSOURCE_ARGS, cf, Constants.ACC_PUBLIC); mb.appendLoadLocal(0); mb.appendLoadLocal(1); mb.appendPutField(srcname); mb.appendLoadLocal(0); mb.appendLoadLocal(2); mb.appendPutField(srcline); mb.appendLoadLocal(0); mb.appendLoadLocal(3); mb.appendPutField(srccol); mb.appendReturn(); mb.codeComplete(false); mb.addMethod(); // add methods for getting the source information mb = new ExceptionMethodBuilder(SOURCENAME_METHODNAME, Type.STRING, EMPTY_ARGS, cf, Constants.ACC_PUBLIC); mb.appendLoadLocal(0); mb.appendGetField(srcname); mb.appendReturn(Type.STRING); mb.codeComplete(false); mb.addMethod(); mb = new ExceptionMethodBuilder(SOURCELINE_METHODNAME, Type.INT, EMPTY_ARGS, cf, Constants.ACC_PUBLIC); mb.appendLoadLocal(0); mb.appendGetField(srcline); mb.appendReturn("int"); mb.codeComplete(false); mb.addMethod(); mb = new ExceptionMethodBuilder(SOURCECOLUMN_METHODNAME, Type.INT, EMPTY_ARGS, cf, Constants.ACC_PUBLIC); mb.appendLoadLocal(0); mb.appendGetField(srccol); mb.appendReturn("int"); mb.codeComplete(false); mb.addMethod(); } } /** * Construct fullly-qualified class and method name for method under * construction. * * @param mb method to be named * @return fully-qualified class and method name */ private String fullMethodName(ContextMethodBuilder mb) { return mb.getClassFile().getName() + '.' + mb.getName(); } /** * Construct fully-qualified class and method name for constructed method. * * @param item method to be named * @return fully-qualified class and method name */ private String fullMethodName(ClassItem item) { return item.getClassFile().getName() + '.' + item.getName(); } /** * Generate call to a constructed unmarshal method. * * @param mb */ private void genUnmarshalCall(String name, ContextMethodBuilder mb) { if (m_isStaticUnmarshal) { mb.appendCallStatic(name, m_unmarshalSignature); } else { mb.appendCallVirtual(name, m_unmarshalSignature); } } /** * Generate call to a constructed marshal method. * * @param mb */ private void genMarshalCall(String name, ContextMethodBuilder mb) { if (m_isStaticMarshal) { mb.appendCallStatic(name, m_marshalSignature); } else { mb.appendCallVirtual(name, m_marshalSignature); } } /** * Generate call to attribute unmarshal method for object. This convenience * method just generates code to call the generated unmarshal method added * to the class definition. The code generated prior to this call must have * loaded a reference to the object to be unmarshalled on the stack, and the * generated code returns the (possibly different, in the case of arrays) * object on the stack. * * @param mb method builder * @throws JiBXException if error in configuration */ private void genUnmarshalAttributeCall(ContextMethodBuilder mb) throws JiBXException { // check if unmarshal method needs to be added to class if (m_unmarshalAttributeMethod == null) { if (m_unmarshalAttributeName == null) { // set up for constructing new method String name = m_container.getBindingRoot().getPrefix() + UNMARSHAL_ATTR_SUFFIX; UnmarshalBuilder meth = new UnmarshalBuilder(name, m_class.getClassFile(), m_class.getMungedFile()); m_unmarshalAttributeName = fullMethodName(meth); m_unmarshalSignature = meth.getSignature(); m_isStaticUnmarshal = meth.isStaticMethod(); // if preset method supplied add code to call it if (m_preSetMethod != null) { meth.loadObject(); genUserMethodCall(true, m_preSetMethod, meth); } // push object being unmarshalled to unmarshaller stack if (!m_isThisBinding) { meth.loadContext(); meth.loadObject(); meth.appendCallVirtual(UNMARSHAL_PUSHTRACKEDOBJECTMETHOD, PUSHOBJECT_SIGNATURE); } // generate the actual unmarshalling code in method meth.loadObject(); m_component.genAttributeUnmarshal(meth); // pop object from unmarshal stack if (!m_isThisBinding) { meth.loadContext(); meth.appendCallVirtual(UNMARSHAL_POPOBJECTMETHOD, POPOBJECT_SIGNATURE); } // if postset method supplied and no content add code to call it if (m_postSetMethod != null && !hasContent()) { genUserMethodCall(true, m_postSetMethod, meth); } // finish by returning object meth.loadObject(); meth.appendReturn(m_class.getClassFile().getName()); // add method to class if (m_lockAttributeUnmarshal) { m_unmarshalAttributeMethod = m_class.getUniqueNamed(meth).getItem(); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -