예제 #1
0
        protected Type EnhanceTypeIntern(Type originalType, String newTypeNamePrefix, IList <IBytecodeBehavior> pendingBehaviors,
                                         IEnhancementHint hint)
        {
            if (pendingBehaviors.Count == 0)
            {
                return(originalType);
            }
            WeakReference originalTypeR = typeToExtendedType.GetWeakReferenceEntry(originalType);

            if (originalTypeR == null)
            {
                throw new Exception("Must never happen");
            }
            String lastTypeHandleName = newTypeNamePrefix;

            newTypeNamePrefix = newTypeNamePrefix.Replace('.', '/');
            StringBuilder sw = new StringBuilder();

            try
            {
                Type currentType = originalType;
                if (currentType.IsInterface)
                {
                    currentType = typeof(Object);
                }
                for (int a = 0, size = pendingBehaviors.Count; a < size; a++)
                {
                    Type newCurrentType = pendingBehaviors[a].GetTypeToExtendFrom(originalType, currentType, hint);
                    if (newCurrentType != null)
                    {
                        currentType = newCurrentType;
                    }
                }
                int iterationCount = 0;

                List <BytecodeBehaviorState> pendingStatesToPostProcess = new List <BytecodeBehaviorState>();
                Type currentContent = currentType; //BytecodeClassLoader.ReadTypeAsBinary(currentType);
                while (pendingBehaviors.Count > 0)
                {
                    iterationCount++;

                    NewType newTypeHandle = NewType.GetObjectType(newTypeNamePrefix + "$A" + iterationCount);
                    lastTypeHandleName = newTypeHandle.ClassName;

                    IBytecodeBehavior[] currentPendingBehaviors = ListUtil.ToArray(pendingBehaviors);
                    pendingBehaviors.Clear();

                    if (currentPendingBehaviors.Length > 0 && Log.DebugEnabled)
                    {
                        Log.Debug("Applying behaviors on " + newTypeHandle.ClassName + ": " + Arrays.ToString(currentPendingBehaviors));
                    }
                    BytecodeEnhancer This            = this;
                    Type             fCurrentContent = currentContent;

                    BytecodeBehaviorState acquiredState = null;
                    Type newContent = BytecodeBehaviorState.SetState(originalType, currentType, newTypeHandle, BeanContext, hint,
                                                                     delegate()
                    {
                        acquiredState = (BytecodeBehaviorState)BytecodeBehaviorState.State;
                        return(This.ExecutePendingBehaviors(fCurrentContent, sw, currentPendingBehaviors, pendingBehaviors));
                    });
                    if (newContent == null)
                    {
                        if (pendingBehaviors.Count > 0)
                        {
                            // "fix" the iterationCount to have a consistent class name hierarchy
                            iterationCount--;
                            continue;
                        }
                        return(currentType);
                    }
                    Type newType = newContent;// BytecodeClassLoader.LoadClass(newTypeHandle.InternalName, newContent);
                    extendedTypeToType.Add(newType, originalTypeR);
                    pendingStatesToPostProcess.Add(acquiredState);
                    currentContent = newContent;
                    currentType    = newType;
                }
                for (int a = 0, size = pendingStatesToPostProcess.Count; a < size; a++)
                {
                    pendingStatesToPostProcess[a].PostProcessCreatedType(currentType);
                }
                return(currentType);
            }
            catch (Exception e)
            {
                BytecodeClassLoader.Save();
                String classByteCode = sw.ToString();
                if (classByteCode.Length > 0)
                {
                    if (TraceDir != null)
                    {
                        LogBytecodeOutput(lastTypeHandleName, classByteCode);
                    }
                    else
                    {
                        throw RuntimeExceptionUtil.Mask(e, "Bytecode:\n" + classByteCode);
                    }
                }
                throw;
            }
        }