예제 #1
0
        public Type ExecutePendingBehaviors(Type currentContent, StringBuilder sw, IBytecodeBehavior[] pendingBehaviors,
                                            IList <IBytecodeBehavior> cascadePendingBehaviors)
        {
            IBytecodeBehaviorState state = BytecodeBehaviorState.State;
            Type content = BytecodeClassLoader.BuildTypeFromParent(state.NewType.ClassName, currentContent, sw, delegate(IClassVisitor cv)
            {
                IBytecodeBehavior[] currPendingBehaviors = pendingBehaviors;
                for (int a = 0; a < currPendingBehaviors.Length; a++)
                {
                    List <IBytecodeBehavior> remainingPendingBehaviors = new List <IBytecodeBehavior>();
                    for (int b = a + 1, sizeB = currPendingBehaviors.Length; b < sizeB; b++)
                    {
                        remainingPendingBehaviors.Add(currPendingBehaviors[b]);
                    }
                    IClassVisitor newCv  = currPendingBehaviors[a].Extend(cv, state, remainingPendingBehaviors, cascadePendingBehaviors);
                    currPendingBehaviors = remainingPendingBehaviors.ToArray();
                    a = -1;
                    if (newCv != null)
                    {
                        cv = newCv;
                    }
                }
                return(cv);
            });

            return(content);
        }
예제 #2
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;
            }
        }
예제 #3
0
        public Type GetEnhancedType(Type typeToEnhance, String newTypeNamePrefix, IEnhancementHint hint)
        {
            Type extendedType = GetEnhancedTypeIntern(typeToEnhance, hint);

            if (extendedType != null)
            {
                return(extendedType);
            }
            lock (writeLock)
            {
                // Concurrent thread may have been faster
                extendedType = GetEnhancedTypeIntern(typeToEnhance, hint);
                if (extendedType != null)
                {
                    return(extendedType);
                }
                if (Log.InfoEnabled)
                {
                    Log.Info("Enhancing " + typeToEnhance + " with hint: " + hint);
                }
                ValueType valueType = DictionaryExtension.ValueOrDefault(typeToExtendedType, typeToEnhance);
                if (valueType == null)
                {
                    valueType = new ValueType();
                    typeToExtendedType.Add(typeToEnhance, valueType);
                }
                else
                {
                    valueType.AddChangeCount();
                    newTypeNamePrefix += "_O" + valueType.ChangeCount;
                }

                List <IBytecodeBehavior> pendingBehaviors = new List <IBytecodeBehavior>();

                IBytecodeBehavior[] extensions = bytecodeBehaviorExtensions.GetExtensions();
                pendingBehaviors.AddRange(extensions);

                Type enhancedType;
                if (pendingBehaviors.Count > 0)
                {
                    enhancedType = EnhanceTypeIntern(typeToEnhance, newTypeNamePrefix, pendingBehaviors, hint);
                }
                else
                {
                    enhancedType = typeToEnhance;
                }
                WeakReference entityTypeR = typeToExtendedType.GetWeakReferenceEntry(typeToEnhance);
                if (entityTypeR == null)
                {
                    throw new Exception("Must never happen");
                }
                hardRefToTypes.Add(enhancedType);
                hardRefToTypes.Add(typeToEnhance);

                if (TraceDir != null)
                {
                    LogBytecodeOutput(enhancedType.FullName, BytecodeClassLoader.ToPrintableBytecode(enhancedType));
                }
                else if (Log.DebugEnabled)
                {
                    // note that this intentionally will only be logged to the console if the traceDir is NOT specified already
                    Log.Debug(BytecodeClassLoader.ToPrintableBytecode(enhancedType));
                }
                try
                {
                    CheckEnhancedTypeConsistency(enhancedType);
                }
                catch (Exception e)
                {
                    if (Log.ErrorEnabled)
                    {
                        Log.Error(BytecodeClassLoader.ToPrintableBytecode(enhancedType), e);
                    }
                    BytecodeClassLoader.Save();
                    throw;
                }
                WeakReference enhancedEntityTypeR = new WeakReference(enhancedType);
                valueType.Put(hint, enhancedEntityTypeR);
                extendedTypeToType.Add(enhancedType, entityTypeR);
                if (Log.InfoEnabled)
                {
                    Log.Info("Enhancement finished successfully with type: " + enhancedType);
                }
                return(enhancedType);
            }
        }