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); }
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; } }
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); } }