Input: Computes the maximum stack size of the method . [CODESPLIT] private void computeMaxStackAndLocal ( ) { // Complete the control flow graph with exception handler blocks. Handler handler = firstHandler ; while ( handler != null ) { Label handlerBlock = handler . handlerPc ; Label handlerRangeBlock = handler . startPc ; Label handlerRangeEnd = handler . endPc ; // Add handlerBlock as a successor of all the basic blocks in the exception handler range. while ( handlerRangeBlock != handlerRangeEnd ) { if ( ( handlerRangeBlock . flags & Label . FLAG_SUBROUTINE_CALLER ) == 0 ) { handlerRangeBlock . outgoingEdges = new Edge ( Edge . EXCEPTION , handlerBlock , handlerRangeBlock . outgoingEdges ) ; } else { // If handlerRangeBlock is a JSR block, add handlerBlock after the first two outgoing // edges to preserve the hypothesis about JSR block successors order (see // {@link #visitJumpInsn}). handlerRangeBlock . outgoingEdges . nextEdge . nextEdge = new Edge ( Edge . EXCEPTION , handlerBlock , handlerRangeBlock . outgoingEdges . nextEdge . nextEdge ) ; } handlerRangeBlock = handlerRangeBlock . nextBasicBlock ; } handler = handler . nextHandler ; } // Complete the control flow graph with the successor blocks of subroutines, if needed. if ( hasSubroutines ) { // First step: find the subroutines. This step determines, for each basic block, to which // subroutine(s) it belongs. Start with the main "subroutine": short numSubroutines = 1 ; firstBasicBlock . markSubroutine ( numSubroutines ) ; // Then, mark the subroutines called by the main subroutine, then the subroutines called by // those called by the main subroutine, etc. for ( short currentSubroutine = 1 ; currentSubroutine <= numSubroutines ; ++ currentSubroutine ) { Label basicBlock = firstBasicBlock ; while ( basicBlock != null ) { if ( ( basicBlock . flags & Label . FLAG_SUBROUTINE_CALLER ) != 0 && basicBlock . subroutineId == currentSubroutine ) { Label jsrTarget = basicBlock . outgoingEdges . nextEdge . successor ; if ( jsrTarget . subroutineId == 0 ) { // If this subroutine has not been marked yet, find its basic blocks. jsrTarget . markSubroutine ( ++ numSubroutines ) ; } } basicBlock = basicBlock . nextBasicBlock ; } } // Second step: find the successors in the control flow graph of each subroutine basic block // 'r' ending with a RET instruction. These successors are the virtual successors of the basic // blocks ending with JSR instructions (see {@link #visitJumpInsn)} that can reach 'r'. Label basicBlock = firstBasicBlock ; while ( basicBlock != null ) { if ( ( basicBlock . flags & Label . FLAG_SUBROUTINE_CALLER ) != 0 ) { // By construction, jsr targets are stored in the second outgoing edge of basic blocks // that ends with a jsr instruction (see {@link #FLAG_SUBROUTINE_CALLER}). Label subroutine = basicBlock . outgoingEdges . nextEdge . successor ; subroutine . addSubroutineRetSuccessors ( basicBlock ) ; } basicBlock = basicBlock . nextBasicBlock ; } } // Data flow algorithm: put the first basic block in a list of blocks to process (i.e. blocks // whose input stack size has changed) and, while there are blocks to process, remove one // from the list, update the input stack size of its successor blocks in the control flow // graph, and add these blocks to the list of blocks to process (if not already done). Label listOfBlocksToProcess = firstBasicBlock ; listOfBlocksToProcess . nextListElement = Label . EMPTY_LIST ; int maxStackSize = maxStack ; while ( listOfBlocksToProcess != Label . EMPTY_LIST ) { // Remove a basic block from the list of blocks to process. Note that we don't reset // basicBlock.nextListElement to null on purpose, to make sure we don't reprocess already // processed basic blocks. Label basicBlock = listOfBlocksToProcess ; listOfBlocksToProcess = listOfBlocksToProcess . nextListElement ; // Compute the (absolute) input stack size and maximum stack size of this block. int inputStackTop = basicBlock . inputStackSize ; int maxBlockStackSize = inputStackTop + basicBlock . outputStackMax ; // Update the absolute maximum stack size of the method. if ( maxBlockStackSize > maxStackSize ) { maxStackSize = maxBlockStackSize ; } // Update the input stack size of the successor blocks of basicBlock in the control flow // graph, and add these blocks to the list of blocks to process, if not already done. Edge outgoingEdge = basicBlock . outgoingEdges ; if ( ( basicBlock . flags & Label . FLAG_SUBROUTINE_CALLER ) != 0 ) { // Ignore the first outgoing edge of the basic blocks ending with a jsr: these are virtual // edges which lead to the instruction just after the jsr, and do not correspond to a // possible execution path (see {@link #visitJumpInsn} and // {@link Label#FLAG_SUBROUTINE_CALLER}). outgoingEdge = outgoingEdge . nextEdge ; } while ( outgoingEdge != null ) { Label successorBlock = outgoingEdge . successor ; if ( successorBlock . nextListElement == null ) { successorBlock . inputStackSize = ( short ) ( outgoingEdge . info == Edge . EXCEPTION ? 1 : inputStackTop + outgoingEdge . info ) ; successorBlock . nextListElement = listOfBlocksToProcess ; listOfBlocksToProcess = successorBlock ; } outgoingEdge = outgoingEdge . nextEdge ; } } this . maxStack = maxStackSize ; }


Input: Adds a successor to { @link #currentBasicBlock } in the control flow graph . [CODESPLIT] private void addSuccessorToCurrentBasicBlock ( final int info , final Label successor ) { currentBasicBlock . outgoingEdges = new Edge ( info , successor , currentBasicBlock . outgoingEdges ) ; }


Input: Ends the current basic block . This method must be used in the case where the current basic block does not have any successor . [CODESPLIT] private void endCurrentBasicBlockWithNoSuccessor ( ) { if ( compute == COMPUTE_ALL_FRAMES ) { Label nextBasicBlock = new Label ( ) ; nextBasicBlock . frame = new Frame ( nextBasicBlock ) ; nextBasicBlock . resolve ( code . data , code . length ) ; lastBasicBlock . nextBasicBlock = nextBasicBlock ; lastBasicBlock = nextBasicBlock ; currentBasicBlock = null ; } else if ( compute == COMPUTE_MAX_STACK_AND_LOCAL ) { currentBasicBlock . outputStackMax = ( short ) maxRelativeStackSize ; currentBasicBlock = null ; } }


Input: Starts the visit of a new stack map frame stored in { @link #currentFrame } . [CODESPLIT] int visitFrameStart ( final int offset , final int numLocal , final int numStack ) { int frameLength = 3 + numLocal + numStack ; if ( currentFrame == null || currentFrame . length < frameLength ) { currentFrame = new int [ frameLength ] ; } currentFrame [ 0 ] = offset ; currentFrame [ 1 ] = numLocal ; currentFrame [ 2 ] = numStack ; return 3 ; }


Input: Ends the visit of { [CODESPLIT] void visitFrameEnd ( ) { if ( previousFrame != null ) { if ( stackMapTableEntries == null ) { stackMapTableEntries = new ByteVector ( ) ; } putFrame ( ) ; ++ stackMapTableNumberOfEntries ; } previousFrame = currentFrame ; currentFrame = null ; }


Input: Compresses and writes { [CODESPLIT] private void putFrame ( ) { final int numLocal = currentFrame [ 1 ] ; final int numStack = currentFrame [ 2 ] ; if ( symbolTable . getMajorVersion ( ) < Opcodes . V1_6 ) { // Generate a StackMap attribute entry, which are always uncompressed. stackMapTableEntries . putShort ( currentFrame [ 0 ] ) . putShort ( numLocal ) ; putAbstractTypes ( 3 , 3 + numLocal ) ; stackMapTableEntries . putShort ( numStack ) ; putAbstractTypes ( 3 + numLocal , 3 + numLocal + numStack ) ; return ; } final int offsetDelta = stackMapTableNumberOfEntries == 0 ? currentFrame [ 0 ] : currentFrame [ 0 ] - previousFrame [ 0 ] - 1 ; final int previousNumlocal = previousFrame [ 1 ] ; final int numLocalDelta = numLocal - previousNumlocal ; int type = Frame . FULL_FRAME ; if ( numStack == 0 ) { switch ( numLocalDelta ) { case - 3 : case - 2 : case - 1 : type = Frame . CHOP_FRAME ; break ; case 0 : type = offsetDelta < 64 ? Frame . SAME_FRAME : Frame . SAME_FRAME_EXTENDED ; break ; case 1 : case 2 : case 3 : type = Frame . APPEND_FRAME ; break ; default : // Keep the FULL_FRAME type. break ; } } else if ( numLocalDelta == 0 && numStack == 1 ) { type = offsetDelta < 63 ? Frame . SAME_LOCALS_1_STACK_ITEM_FRAME : Frame . SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED ; } if ( type != Frame . FULL_FRAME ) { // Verify if locals are the same as in the previous frame. int frameIndex = 3 ; for ( int i = 0 ; i < previousNumlocal && i < numLocal ; i ++ ) { if ( currentFrame [ frameIndex ] != previousFrame [ frameIndex ] ) { type = Frame . FULL_FRAME ; break ; } frameIndex ++ ; } } switch ( type ) { case Frame . SAME_FRAME : stackMapTableEntries . putByte ( offsetDelta ) ; break ; case Frame . SAME_LOCALS_1_STACK_ITEM_FRAME : stackMapTableEntries . putByte ( Frame . SAME_LOCALS_1_STACK_ITEM_FRAME + offsetDelta ) ; putAbstractTypes ( 3 + numLocal , 4 + numLocal ) ; break ; case Frame . SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED : stackMapTableEntries . putByte ( Frame . SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED ) . putShort ( offsetDelta ) ; putAbstractTypes ( 3 + numLocal , 4 + numLocal ) ; break ; case Frame . SAME_FRAME_EXTENDED : stackMapTableEntries . putByte ( Frame . SAME_FRAME_EXTENDED ) . putShort ( offsetDelta ) ; break ; case Frame . CHOP_FRAME : stackMapTableEntries . putByte ( Frame . SAME_FRAME_EXTENDED + numLocalDelta ) . putShort ( offsetDelta ) ; break ; case Frame . APPEND_FRAME : stackMapTableEntries . putByte ( Frame . SAME_FRAME_EXTENDED + numLocalDelta ) . putShort ( offsetDelta ) ; putAbstractTypes ( 3 + previousNumlocal , 3 + numLocal ) ; break ; case Frame . FULL_FRAME : default : stackMapTableEntries . putByte ( Frame . FULL_FRAME ) . putShort ( offsetDelta ) . putShort ( numLocal ) ; putAbstractTypes ( 3 , 3 + numLocal ) ; stackMapTableEntries . putShort ( numStack ) ; putAbstractTypes ( 3 + numLocal , 3 + numLocal + numStack ) ; break ; } }


Input: Puts some abstract types of { @link #currentFrame } in { @link #stackMapTableEntries } using the JVMS verification_type_info format used in StackMapTable attributes . [CODESPLIT] private void putAbstractTypes ( final int start , final int end ) { for ( int i = start ; i < end ; ++ i ) { Frame . putAbstractType ( symbolTable , currentFrame [ i ] , stackMapTableEntries ) ; } }


Input: Puts the given public API frame element type in { @link #stackMapTableEntries } using the JVMS verification_type_info format used in StackMapTable attributes . [CODESPLIT] private void putFrameType ( final Object type ) { if ( type instanceof Integer ) { stackMapTableEntries . putByte ( ( ( Integer ) type ) . intValue ( ) ) ; } else if ( type instanceof String ) { stackMapTableEntries . putByte ( Frame . ITEM_OBJECT ) . putShort ( symbolTable . addConstantClass ( ( String ) type ) . index ) ; } else { stackMapTableEntries . putByte ( Frame . ITEM_UNINITIALIZED ) . putShort ( ( ( Label ) type ) . bytecodeOffset ) ; } }


Input: Returns whether the attributes of this method can be copied from the attributes of the given method ( assuming there is no method visitor between the given ClassReader and this MethodWriter ) . This method should only be called just after this MethodWriter has been created and before any content is visited . It returns true if the attributes corresponding to the constructor arguments ( at most a Signature an Exception a Deprecated and a Synthetic attribute ) are the same as the corresponding attributes in the given method . [CODESPLIT] boolean canCopyMethodAttributes ( final ClassReader source , final int methodInfoOffset , final int methodInfoLength , final boolean hasSyntheticAttribute , final boolean hasDeprecatedAttribute , final int descriptorIndex , final int signatureIndex , final int exceptionsOffset ) { // If the method descriptor has changed, with more locals than the max_locals field of the // original Code attribute, if any, then the original method attributes can't be copied. A // conservative check on the descriptor changes alone ensures this (being more precise is not // worth the additional complexity, because these cases should be rare -- if a transform changes // a method descriptor, most of the time it needs to change the method's code too). if ( source != symbolTable . getSource ( ) || descriptorIndex != this . descriptorIndex || signatureIndex != this . signatureIndex || hasDeprecatedAttribute != ( ( accessFlags & Opcodes . ACC_DEPRECATED ) != 0 ) ) { return false ; } boolean needSyntheticAttribute = symbolTable . getMajorVersion ( ) < Opcodes . V1_5 && ( accessFlags & Opcodes . ACC_SYNTHETIC ) != 0 ; if ( hasSyntheticAttribute != needSyntheticAttribute ) { return false ; } if ( exceptionsOffset == 0 ) { if ( numberOfExceptions != 0 ) { return false ; } } else if ( source . readUnsignedShort ( exceptionsOffset ) == numberOfExceptions ) { int currentExceptionOffset = exceptionsOffset + 2 ; for ( int i = 0 ; i < numberOfExceptions ; ++ i ) { if ( source . readUnsignedShort ( currentExceptionOffset ) != exceptionIndexTable [ i ] ) { return false ; } currentExceptionOffset += 2 ; } } // Don't copy the attributes yet, instead store their location in the source class reader so // they can be copied later, in {@link #putMethodInfo}. Note that we skip the 6 header bytes // of the method_info JVMS structure. this . sourceOffset = methodInfoOffset + 6 ; this . sourceLength = methodInfoLength - 6 ; return true ; }


Input: Returns the size of the method_info JVMS structure generated by this MethodWriter . Also add the names of the attributes of this method in the constant pool . [CODESPLIT] int computeMethodInfoSize ( ) { // If this method_info must be copied from an existing one, the size computation is trivial. if ( sourceOffset != 0 ) { // sourceLength excludes the first 6 bytes for access_flags, name_index and descriptor_index. return 6 + sourceLength ; } // 2 bytes each for access_flags, name_index, descriptor_index and attributes_count. int size = 8 ; // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS. if ( code . length > 0 ) { if ( code . length > 65535 ) { throw new MethodTooLargeException ( symbolTable . getClassName ( ) , name , descriptor , code . length ) ; } symbolTable . addConstantUtf8 ( Constants . CODE ) ; // The Code attribute has 6 header bytes, plus 2, 2, 4 and 2 bytes respectively for max_stack, // max_locals, code_length and attributes_count, plus the bytecode and the exception table. size += 16 + code . length + Handler . getExceptionTableSize ( firstHandler ) ; if ( stackMapTableEntries != null ) { boolean useStackMapTable = symbolTable . getMajorVersion ( ) >= Opcodes . V1_6 ; symbolTable . addConstantUtf8 ( useStackMapTable ? Constants . STACK_MAP_TABLE : "StackMap" ) ; // 6 header bytes and 2 bytes for number_of_entries. size += 8 + stackMapTableEntries . length ; } if ( lineNumberTable != null ) { symbolTable . addConstantUtf8 ( Constants . LINE_NUMBER_TABLE ) ; // 6 header bytes and 2 bytes for line_number_table_length. size += 8 + lineNumberTable . length ; } if ( localVariableTable != null ) { symbolTable . addConstantUtf8 ( Constants . LOCAL_VARIABLE_TABLE ) ; // 6 header bytes and 2 bytes for local_variable_table_length. size += 8 + localVariableTable . length ; } if ( localVariableTypeTable != null ) { symbolTable . addConstantUtf8 ( Constants . LOCAL_VARIABLE_TYPE_TABLE ) ; // 6 header bytes and 2 bytes for local_variable_type_table_length. size += 8 + localVariableTypeTable . length ; } if ( lastCodeRuntimeVisibleTypeAnnotation != null ) { size += lastCodeRuntimeVisibleTypeAnnotation . computeAnnotationsSize ( Constants . RUNTIME_VISIBLE_TYPE_ANNOTATIONS ) ; } if ( lastCodeRuntimeInvisibleTypeAnnotation != null ) { size += lastCodeRuntimeInvisibleTypeAnnotation . computeAnnotationsSize ( Constants . RUNTIME_INVISIBLE_TYPE_ANNOTATIONS ) ; } if ( firstCodeAttribute != null ) { size += firstCodeAttribute . computeAttributesSize ( symbolTable , code . data , code . length , maxStack , maxLocals ) ; } } if ( numberOfExceptions > 0 ) { symbolTable . addConstantUtf8 ( Constants . EXCEPTIONS ) ; size += 8 + 2 * numberOfExceptions ; } boolean useSyntheticAttribute = symbolTable . getMajorVersion ( ) < Opcodes . V1_5 ; if ( ( accessFlags & Opcodes . ACC_SYNTHETIC ) != 0 && useSyntheticAttribute ) { symbolTable . addConstantUtf8 ( Constants . SYNTHETIC ) ; size += 6 ; } if ( signatureIndex != 0 ) { symbolTable . addConstantUtf8 ( Constants . SIGNATURE ) ; size += 8 ; } if ( ( accessFlags & Opcodes . ACC_DEPRECATED ) != 0 ) { symbolTable . addConstantUtf8 ( Constants . DEPRECATED ) ; size += 6 ; } if ( lastRuntimeVisibleAnnotation != null ) { size += lastRuntimeVisibleAnnotation . computeAnnotationsSize ( Constants . RUNTIME_VISIBLE_ANNOTATIONS ) ; } if ( lastRuntimeInvisibleAnnotation != null ) { size += lastRuntimeInvisibleAnnotation . computeAnnotationsSize ( Constants . RUNTIME_INVISIBLE_ANNOTATIONS ) ; } if ( lastRuntimeVisibleParameterAnnotations != null ) { size += AnnotationWriter . computeParameterAnnotationsSize ( Constants . RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS , lastRuntimeVisibleParameterAnnotations , visibleAnnotableParameterCount == 0 ? lastRuntimeVisibleParameterAnnotations . length : visibleAnnotableParameterCount ) ; } if ( lastRuntimeInvisibleParameterAnnotations != null ) { size += AnnotationWriter . computeParameterAnnotationsSize ( Constants . RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS , lastRuntimeInvisibleParameterAnnotations , invisibleAnnotableParameterCount == 0 ? lastRuntimeInvisibleParameterAnnotations . length : invisibleAnnotableParameterCount ) ; } if ( lastRuntimeVisibleTypeAnnotation != null ) { size += lastRuntimeVisibleTypeAnnotation . computeAnnotationsSize ( Constants . RUNTIME_VISIBLE_TYPE_ANNOTATIONS ) ; } if ( lastRuntimeInvisibleTypeAnnotation != null ) { size += lastRuntimeInvisibleTypeAnnotation . computeAnnotationsSize ( Constants . RUNTIME_INVISIBLE_TYPE_ANNOTATIONS ) ; } if ( defaultValue != null ) { symbolTable . addConstantUtf8 ( Constants . ANNOTATION_DEFAULT ) ; size += 6 + defaultValue . length ; } if ( parameters != null ) { symbolTable . addConstantUtf8 ( Constants . METHOD_PARAMETERS ) ; // 6 header bytes and 1 byte for parameters_count. size += 7 + parameters . length ; } if ( firstAttribute != null ) { size += firstAttribute . computeAttributesSize ( symbolTable ) ; } return size ; }


Input: Puts the content of the method_info JVMS structure generated by this MethodWriter into the given ByteVector . [CODESPLIT] void putMethodInfo ( final ByteVector output ) { boolean useSyntheticAttribute = symbolTable . getMajorVersion ( ) < Opcodes . V1_5 ; int mask = useSyntheticAttribute ? Opcodes . ACC_SYNTHETIC : 0 ; output . putShort ( accessFlags & ~ mask ) . putShort ( nameIndex ) . putShort ( descriptorIndex ) ; // If this method_info must be copied from an existing one, copy it now and return early. if ( sourceOffset != 0 ) { output . putByteArray ( symbolTable . getSource ( ) . b , sourceOffset , sourceLength ) ; return ; } // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS. int attributeCount = 0 ; if ( code . length > 0 ) { ++ attributeCount ; } if ( numberOfExceptions > 0 ) { ++ attributeCount ; } if ( ( accessFlags & Opcodes . ACC_SYNTHETIC ) != 0 && useSyntheticAttribute ) { ++ attributeCount ; } if ( signatureIndex != 0 ) { ++ attributeCount ; } if ( ( accessFlags & Opcodes . ACC_DEPRECATED ) != 0 ) { ++ attributeCount ; } if ( lastRuntimeVisibleAnnotation != null ) { ++ attributeCount ; } if ( lastRuntimeInvisibleAnnotation != null ) { ++ attributeCount ; } if ( lastRuntimeVisibleParameterAnnotations != null ) { ++ attributeCount ; } if ( lastRuntimeInvisibleParameterAnnotations != null ) { ++ attributeCount ; } if ( lastRuntimeVisibleTypeAnnotation != null ) { ++ attributeCount ; } if ( lastRuntimeInvisibleTypeAnnotation != null ) { ++ attributeCount ; } if ( defaultValue != null ) { ++ attributeCount ; } if ( parameters != null ) { ++ attributeCount ; } if ( firstAttribute != null ) { attributeCount += firstAttribute . getAttributeCount ( ) ; } // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS. output . putShort ( attributeCount ) ; if ( code . length > 0 ) { // 2, 2, 4 and 2 bytes respectively for max_stack, max_locals, code_length and // attributes_count, plus the bytecode and the exception table. int size = 10 + code . length + Handler . getExceptionTableSize ( firstHandler ) ; int codeAttributeCount = 0 ; if ( stackMapTableEntries != null ) { // 6 header bytes and 2 bytes for number_of_entries. size += 8 + stackMapTableEntries . length ; ++ codeAttributeCount ; } if ( lineNumberTable != null ) { // 6 header bytes and 2 bytes for line_number_table_length. size += 8 + lineNumberTable . length ; ++ codeAttributeCount ; } if ( localVariableTable != null ) { // 6 header bytes and 2 bytes for local_variable_table_length. size += 8 + localVariableTable . length ; ++ codeAttributeCount ; } if ( localVariableTypeTable != null ) { // 6 header bytes and 2 bytes for local_variable_type_table_length. size += 8 + localVariableTypeTable . length ; ++ codeAttributeCount ; } if ( lastCodeRuntimeVisibleTypeAnnotation != null ) { size += lastCodeRuntimeVisibleTypeAnnotation . computeAnnotationsSize ( Constants . RUNTIME_VISIBLE_TYPE_ANNOTATIONS ) ; ++ codeAttributeCount ; } if ( lastCodeRuntimeInvisibleTypeAnnotation != null ) { size += lastCodeRuntimeInvisibleTypeAnnotation . computeAnnotationsSize ( Constants . RUNTIME_INVISIBLE_TYPE_ANNOTATIONS ) ; ++ codeAttributeCount ; } if ( firstCodeAttribute != null ) { size += firstCodeAttribute . computeAttributesSize ( symbolTable , code . data , code . length , maxStack , maxLocals ) ; codeAttributeCount += firstCodeAttribute . getAttributeCount ( ) ; } output . putShort ( symbolTable . addConstantUtf8 ( Constants . CODE ) ) . putInt ( size ) . putShort ( maxStack ) . putShort ( maxLocals ) . putInt ( code . length ) . putByteArray ( code . data , 0 , code . length ) ; Handler . putExceptionTable ( firstHandler , output ) ; output . putShort ( codeAttributeCount ) ; if ( stackMapTableEntries != null ) { boolean useStackMapTable = symbolTable . getMajorVersion ( ) >= Opcodes . V1_6 ; output . putShort ( symbolTable . addConstantUtf8 ( useStackMapTable ? Constants . STACK_MAP_TABLE : "StackMap" ) ) . putInt ( 2 + stackMapTableEntries . length ) . putShort ( stackMapTableNumberOfEntries ) . putByteArray ( stackMapTableEntries . data , 0 , stackMapTableEntries . length ) ; } if ( lineNumberTable != null ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . LINE_NUMBER_TABLE ) ) . putInt ( 2 + lineNumberTable . length ) . putShort ( lineNumberTableLength ) . putByteArray ( lineNumberTable . data , 0 , lineNumberTable . length ) ; } if ( localVariableTable != null ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . LOCAL_VARIABLE_TABLE ) ) . putInt ( 2 + localVariableTable . length ) . putShort ( localVariableTableLength ) . putByteArray ( localVariableTable . data , 0 , localVariableTable . length ) ; } if ( localVariableTypeTable != null ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . LOCAL_VARIABLE_TYPE_TABLE ) ) . putInt ( 2 + localVariableTypeTable . length ) . putShort ( localVariableTypeTableLength ) . putByteArray ( localVariableTypeTable . data , 0 , localVariableTypeTable . length ) ; } if ( lastCodeRuntimeVisibleTypeAnnotation != null ) { lastCodeRuntimeVisibleTypeAnnotation . putAnnotations ( symbolTable . addConstantUtf8 ( Constants . RUNTIME_VISIBLE_TYPE_ANNOTATIONS ) , output ) ; } if ( lastCodeRuntimeInvisibleTypeAnnotation != null ) { lastCodeRuntimeInvisibleTypeAnnotation . putAnnotations ( symbolTable . addConstantUtf8 ( Constants . RUNTIME_INVISIBLE_TYPE_ANNOTATIONS ) , output ) ; } if ( firstCodeAttribute != null ) { firstCodeAttribute . putAttributes ( symbolTable , code . data , code . length , maxStack , maxLocals , output ) ; } } if ( numberOfExceptions > 0 ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . EXCEPTIONS ) ) . putInt ( 2 + 2 * numberOfExceptions ) . putShort ( numberOfExceptions ) ; for ( int exceptionIndex : exceptionIndexTable ) { output . putShort ( exceptionIndex ) ; } } if ( ( accessFlags & Opcodes . ACC_SYNTHETIC ) != 0 && useSyntheticAttribute ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . SYNTHETIC ) ) . putInt ( 0 ) ; } if ( signatureIndex != 0 ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . SIGNATURE ) ) . putInt ( 2 ) . putShort ( signatureIndex ) ; } if ( ( accessFlags & Opcodes . ACC_DEPRECATED ) != 0 ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . DEPRECATED ) ) . putInt ( 0 ) ; } if ( lastRuntimeVisibleAnnotation != null ) { lastRuntimeVisibleAnnotation . putAnnotations ( symbolTable . addConstantUtf8 ( Constants . RUNTIME_VISIBLE_ANNOTATIONS ) , output ) ; } if ( lastRuntimeInvisibleAnnotation != null ) { lastRuntimeInvisibleAnnotation . putAnnotations ( symbolTable . addConstantUtf8 ( Constants . RUNTIME_INVISIBLE_ANNOTATIONS ) , output ) ; } if ( lastRuntimeVisibleParameterAnnotations != null ) { AnnotationWriter . putParameterAnnotations ( symbolTable . addConstantUtf8 ( Constants . RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS ) , lastRuntimeVisibleParameterAnnotations , visibleAnnotableParameterCount == 0 ? lastRuntimeVisibleParameterAnnotations . length : visibleAnnotableParameterCount , output ) ; } if ( lastRuntimeInvisibleParameterAnnotations != null ) { AnnotationWriter . putParameterAnnotations ( symbolTable . addConstantUtf8 ( Constants . RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS ) , lastRuntimeInvisibleParameterAnnotations , invisibleAnnotableParameterCount == 0 ? lastRuntimeInvisibleParameterAnnotations . length : invisibleAnnotableParameterCount , output ) ; } if ( lastRuntimeVisibleTypeAnnotation != null ) { lastRuntimeVisibleTypeAnnotation . putAnnotations ( symbolTable . addConstantUtf8 ( Constants . RUNTIME_VISIBLE_TYPE_ANNOTATIONS ) , output ) ; } if ( lastRuntimeInvisibleTypeAnnotation != null ) { lastRuntimeInvisibleTypeAnnotation . putAnnotations ( symbolTable . addConstantUtf8 ( Constants . RUNTIME_INVISIBLE_TYPE_ANNOTATIONS ) , output ) ; } if ( defaultValue != null ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . ANNOTATION_DEFAULT ) ) . putInt ( defaultValue . length ) . putByteArray ( defaultValue . data , 0 , defaultValue . length ) ; } if ( parameters != null ) { output . putShort ( symbolTable . addConstantUtf8 ( Constants . METHOD_PARAMETERS ) ) . putInt ( 1 + parameters . length ) . putByte ( parametersCount ) . putByteArray ( parameters . data , 0 , parameters . length ) ; } if ( firstAttribute != null ) { firstAttribute . putAttributes ( symbolTable , output ) ; } }


Input: Collects the attributes of this method into the given set of attribute prototypes . [CODESPLIT] final void collectAttributePrototypes ( final Attribute . Set attributePrototypes ) { attributePrototypes . addAttributes ( firstAttribute ) ; attributePrototypes . addAttributes ( firstCodeAttribute ) ; }


Input: { [CODESPLIT] @ Override protected WorkData process ( final ClassReader cr , final TargetClassInfoReader targetClassInfoReader ) { InvokeClassBuilder icb = new InvokeClassBuilder ( destClassWriter , proxetta . getAspects ( new InvokeAspect [ 0 ] ) , resolveClassNameSuffix ( ) , requestedProxyClassName , targetClassInfoReader ) ; cr . accept ( icb , 0 ) ; return icb . getWorkData ( ) ; }


Input: Inject context into target . [CODESPLIT] public void injectContext ( final Object targetObject ) { final Class targetType = targetObject . getClass ( ) ; final ScopeData scopeData = scopeDataInspector . inspectClassScopesWithCache ( targetType ) ; final Targets targets = new Targets ( targetObject , scopeData ) ; // inject no context scopeResolver . forEachScope ( madvocScope -> madvocScope . inject ( targets ) ) ; // inject special case scopeResolver . forScope ( ParamsScope . class , scope -> scope . inject ( targets ) ) ; // inject servlet context final ServletContext servletContext = madvocController . getApplicationContext ( ) ; if ( servletContext != null ) { scopeResolver . forEachScope ( madvocScope -> madvocScope . inject ( servletContext , targets ) ) ; } }


Input: Parses selector string . Returns <code > null< / code > if no selector can be parsed . [CODESPLIT] public List < CssSelector > parse ( ) { try { lexer . yylex ( ) ; if ( lexer . selectors . isEmpty ( ) ) { return null ; } // fixes last combinator CssSelector last = lexer . selectors . get ( lexer . selectors . size ( ) - 1 ) ; if ( last . getCombinator ( ) == Combinator . DESCENDANT ) { last . setCombinator ( null ) ; } // set previous css selector CssSelector prevCssSelector = null ; for ( CssSelector cssSelector : lexer . selectors ) { if ( prevCssSelector != null ) { cssSelector . setPrevCssSelector ( prevCssSelector ) ; } prevCssSelector = cssSelector ; } return lexer . selectors ; } catch ( IOException ioex ) { throw new CSSellyException ( ioex ) ; } }


Input: Parses string of selectors ( separated with <b > < / b > ) . Returns list of { [CODESPLIT] public static List < List < CssSelector > > parse ( final String query ) { String [ ] singleQueries = StringUtil . splitc ( query , ' ' ) ; List < List < CssSelector > > selectors = new ArrayList <> ( singleQueries . length ) ; for ( String singleQuery : singleQueries ) { selectors . add ( new CSSelly ( singleQuery ) . parse ( ) ) ; } return selectors ; }


Input: Registers pseudo class . [CODESPLIT] public static void registerPseudoClass ( final Class < ? extends PseudoClass > pseudoClassType ) { PseudoClass pseudoClass ; try { pseudoClass = ClassUtil . newInstance ( pseudoClassType ) ; } catch ( Exception ex ) { throw new CSSellyException ( ex ) ; } PSEUDO_CLASS_MAP . put ( pseudoClass . getPseudoClassName ( ) , pseudoClass ) ; }


Input: Lookups pseudo class for given pseudo class name . [CODESPLIT] public static PseudoClass lookupPseudoClass ( final String pseudoClassName ) { PseudoClass pseudoClass = PSEUDO_CLASS_MAP . get ( pseudoClassName ) ; if ( pseudoClass == null ) { throw new CSSellyException ( "Unsupported pseudo class: " + pseudoClassName ) ; } return pseudoClass ; }


Input: Accepts node within selected results . Invoked after results are matched . [CODESPLIT] @ Override public boolean accept ( final List < Node > currentResults , final Node node , final int index ) { return pseudoClass . match ( currentResults , node , index ) ; }


Input: Invokes an action asynchronously by submitting it to the thread pool . [CODESPLIT] public void invoke ( final ActionRequest actionRequest ) { if ( executorService == null ) { throw new MadvocException ( "No action is marked as async!" ) ; } final HttpServletRequest servletRequest = actionRequest . getHttpServletRequest ( ) ; log . debug ( ( ) -> "Async call to: " + actionRequest ) ; final AsyncContext asyncContext = servletRequest . startAsync ( ) ; executorService . submit ( ( ) -> { try { actionRequest . invoke ( ) ; } catch ( Exception ex ) { log . error ( "Invoking async action path failed: " , ExceptionUtil . unwrapThrowable ( ex ) ) ; } finally { asyncContext . complete ( ) ; } } ) ; }


Input: Closes silently the closable object . If it is { [CODESPLIT] public static void close ( final Closeable closeable ) { if ( closeable != null ) { if ( closeable instanceof Flushable ) { try { ( ( Flushable ) closeable ) . flush ( ) ; } catch ( IOException ignored ) { } } try { closeable . close ( ) ; } catch ( IOException ignored ) { } } }


Input: Copies specified number of characters from { @link Reader } to { @link Writer } using buffer . { @link Reader } and { @link Writer } don t have to be wrapped to buffered since copying is already optimized . [CODESPLIT] public static int copy ( final Reader input , final Writer output , final int count ) throws IOException { if ( count == ALL ) { return copy ( input , output ) ; } int numToRead = count ; char [ ] buffer = new char [ numToRead ] ; int totalRead = ZERO ; int read ; while ( numToRead > ZERO ) { read = input . read ( buffer , ZERO , bufferSize ( numToRead ) ) ; if ( read == NEGATIVE_ONE ) { break ; } output . write ( buffer , ZERO , read ) ; numToRead = numToRead - read ; totalRead = totalRead + read ; } output . flush ( ) ; return totalRead ; }


Input: Copies specified number of bytes from { @link InputStream } to { @link OutputStream } using buffer . { @link InputStream } and { @link OutputStream } don t have to be wrapped to buffered since copying is already optimized . [CODESPLIT] public static int copy ( final InputStream input , final OutputStream output , final int count ) throws IOException { if ( count == ALL ) { return copy ( input , output ) ; } int numToRead = count ; byte [ ] buffer = new byte [ numToRead ] ; int totalRead = ZERO ; int read ; while ( numToRead > ZERO ) { read = input . read ( buffer , ZERO , bufferSize ( numToRead ) ) ; if ( read == NEGATIVE_ONE ) { break ; } output . write ( buffer , ZERO , read ) ; numToRead = numToRead - read ; totalRead = totalRead + read ; } output . flush ( ) ; return totalRead ; }


Input: Reads all available bytes from { @link InputStream } as a byte array . Uses { @link InputStream#available () } to determine the size of input stream . This is the fastest method for reading { @link InputStream } to byte array but depends on { @link InputStream } implementation of { @link InputStream#available () } . [CODESPLIT] public static byte [ ] readAvailableBytes ( final InputStream input ) throws IOException { int numToRead = input . available ( ) ; byte [ ] buffer = new byte [ numToRead ] ; int totalRead = ZERO ; int read ; while ( ( totalRead < numToRead ) && ( read = input . read ( buffer , totalRead , numToRead - totalRead ) ) >= ZERO ) { totalRead = totalRead + read ; } if ( totalRead < numToRead ) { throw new IOException ( "Failed to completely read InputStream" ) ; } return buffer ; }


Input: Copies { @link Reader } to { @link OutputStream } using buffer and specified encoding . [CODESPLIT] public static < T extends OutputStream > T copy ( final Reader input , final T output , final String encoding , final int count ) throws IOException { try ( Writer out = outputStreamWriterOf ( output , encoding ) ) { copy ( input , out , count ) ; return output ; } }


Input: Copies { @link InputStream } to a new { @link FastByteArrayOutputStream } using buffer and specified encoding . [CODESPLIT] public static FastByteArrayOutputStream copyToOutputStream ( final InputStream input , final int count ) throws IOException { try ( FastByteArrayOutputStream output = createFastByteArrayOutputStream ( ) ) { copy ( input , output , count ) ; return output ; } }


Input: Copies { @link Reader } to a new { @link FastByteArrayOutputStream } using buffer and specified encoding . [CODESPLIT] public static FastByteArrayOutputStream copyToOutputStream ( final Reader input , final String encoding , final int count ) throws IOException { try ( FastByteArrayOutputStream output = createFastByteArrayOutputStream ( ) ) { copy ( input , output , encoding , count ) ; return output ; } }


Input: Copies { @link InputStream } to a new { @link FastCharArrayWriter } using buffer and specified encoding . [CODESPLIT] public static FastCharArrayWriter copy ( final InputStream input , final String encoding , final int count ) throws IOException { try ( FastCharArrayWriter output = createFastCharArrayWriter ( ) ) { copy ( input , output , encoding , count ) ; return output ; } }


Input: Copies { @link Reader } to a new { @link FastCharArrayWriter } using buffer and specified encoding . [CODESPLIT] public static FastCharArrayWriter copy ( final Reader input , final int count ) throws IOException { try ( FastCharArrayWriter output = createFastCharArrayWriter ( ) ) { copy ( input , output , count ) ; return output ; } }


Input: Returns new { @link InputStreamReader } using specified { @link InputStream } and encoding . [CODESPLIT] public static InputStreamReader inputStreamReadeOf ( final InputStream input , final String encoding ) throws UnsupportedEncodingException { return new InputStreamReader ( input , encoding ) ; }


Input: Returns new { @link OutputStreamWriter } using specified { @link OutputStream } and encoding . [CODESPLIT] public static OutputStreamWriter outputStreamWriterOf ( final OutputStream output , final String encoding ) throws UnsupportedEncodingException { return new OutputStreamWriter ( output , encoding ) ; }


Input: Returns all bean property names . [CODESPLIT] protected String [ ] getAllBeanPropertyNames ( final Class type , final boolean declared ) { ClassDescriptor classDescriptor = ClassIntrospector . get ( ) . lookup ( type ) ; PropertyDescriptor [ ] propertyDescriptors = classDescriptor . getAllPropertyDescriptors ( ) ; ArrayList < String > names = new ArrayList <> ( propertyDescriptors . length ) ; for ( PropertyDescriptor propertyDescriptor : propertyDescriptors ) { MethodDescriptor getter = propertyDescriptor . getReadMethodDescriptor ( ) ; if ( getter != null ) { if ( getter . matchDeclared ( declared ) ) { names . add ( propertyDescriptor . getName ( ) ) ; } } else if ( includeFields ) { FieldDescriptor field = propertyDescriptor . getFieldDescriptor ( ) ; if ( field != null ) { if ( field . matchDeclared ( declared ) ) { names . add ( field . getName ( ) ) ; } } } } return names . toArray ( new String [ 0 ] ) ; }


Input: Returns an array of bean properties . If bean is a <code > Map< / code > all its keys will be returned . [CODESPLIT] protected String [ ] resolveProperties ( final Object bean , final boolean declared ) { String [ ] properties ; if ( bean instanceof Map ) { Set keys = ( ( Map ) bean ) . keySet ( ) ; properties = new String [ keys . size ( ) ] ; int ndx = 0 ; for ( Object key : keys ) { properties [ ndx ] = key . toString ( ) ; ndx ++ ; } } else { properties = getAllBeanPropertyNames ( bean . getClass ( ) , declared ) ; } return properties ; }


Input: Starts visiting properties . [CODESPLIT] public void visit ( ) { String [ ] properties = resolveProperties ( source , declared ) ; for ( String name : properties ) { if ( name == null ) { continue ; } if ( ! rules . match ( name , blacklist ) ) { continue ; } Object value ; String propertyName = name ; if ( isSourceMap ) { propertyName = LEFT_SQ_BRACKET + name + RIGHT_SQ_BRACKET ; } if ( declared ) { value = BeanUtil . declared . getProperty ( source , propertyName ) ; } else { value = BeanUtil . pojo . getProperty ( source , propertyName ) ; } if ( value == null && ignoreNullValues ) { continue ; } if ( value instanceof String && StringUtil . isEmpty ( ( String ) value ) ) { continue ; } visitProperty ( name , value ) ; } }


Input: Compares property name to the rules . [CODESPLIT] @ Override public boolean accept ( final String propertyName , final String rule , final boolean include ) { return propertyName . equals ( rule ) ; }


Input: { [CODESPLIT] @ Override public ClassDescriptor lookup ( final Class type ) { return cache . get ( type , ( ) -> new ClassDescriptor ( type , scanAccessible , enhancedProperties , includeFieldsAsProperties , propertyFieldPrefix ) ) ; }


Input: Resolve method injection points in given class . [CODESPLIT] public MethodInjectionPoint [ ] resolve ( final Class type ) { // lookup methods ClassDescriptor cd = ClassIntrospector . get ( ) . lookup ( type ) ; List < MethodInjectionPoint > list = new ArrayList <> ( ) ; MethodDescriptor [ ] allMethods = cd . getAllMethodDescriptors ( ) ; for ( MethodDescriptor methodDescriptor : allMethods ) { Method method = methodDescriptor . getMethod ( ) ; if ( ClassUtil . isBeanPropertySetter ( method ) ) { // ignore setters continue ; } if ( method . getParameterTypes ( ) . length == 0 ) { // ignore methods with no argument continue ; } BeanReferences [ ] references = referencesResolver . readAllReferencesFromAnnotation ( method ) ; if ( references != null ) { MethodInjectionPoint methodInjectionPoint = new MethodInjectionPoint ( method , references ) ; list . add ( methodInjectionPoint ) ; } } final MethodInjectionPoint [ ] methodInjectionPoints ; if ( list . isEmpty ( ) ) { methodInjectionPoints = MethodInjectionPoint . EMPTY ; } else { methodInjectionPoints = list . toArray ( new MethodInjectionPoint [ 0 ] ) ; } return methodInjectionPoints ; }


Input: Reads filter config parameters and set into destination target . [CODESPLIT] protected void readFilterConfigParameters ( final FilterConfig filterConfig , final Object target , final String ... parameters ) { for ( String parameter : parameters ) { String value = filterConfig . getInitParameter ( parameter ) ; if ( value != null ) { BeanUtil . declared . setProperty ( target , parameter , value ) ; } } }


Input: Creates { [CODESPLIT] protected HtmlStaplerBundlesManager createBundleManager ( final ServletContext servletContext , final Strategy strategy ) { String webRoot = servletContext . getRealPath ( StringPool . EMPTY ) ; String contextPath = ServletUtil . getContextPath ( servletContext ) ; return new HtmlStaplerBundlesManager ( contextPath , webRoot , strategy ) ; }


Input: Outputs bundle file to the response . [CODESPLIT] protected void sendBundleFile ( final HttpServletResponse resp , final File bundleFile ) throws IOException { OutputStream out = resp . getOutputStream ( ) ; FileInputStream fileInputStream = new FileInputStream ( bundleFile ) ; try { StreamUtil . copy ( fileInputStream , out ) ; } finally { StreamUtil . close ( fileInputStream ) ; } }


Input: Configures { [CODESPLIT] public void configure ( ) { long elapsed = System . currentTimeMillis ( ) ; final ClassScanner classScanner = new ClassScanner ( ) ; classScanner . detectEntriesMode ( true ) ; classScanner . scanDefaultClasspath ( ) ; classScannerConsumers . accept ( classScanner ) ; registerAsConsumer ( classScanner ) ; try { classScanner . start ( ) ; } catch ( Exception ex ) { throw new DbOomException ( "Scan classpath error" , ex ) ; } elapsed = System . currentTimeMillis ( ) - elapsed ; if ( log . isInfoEnabled ( ) ) { log . info ( "DbEntityManager configured in " + elapsed + "ms. Total entities: " + dbEntityManager . getTotalNames ( ) ) ; } }


Input: Registers a class consumer that registers only those annotated with { [CODESPLIT] public void registerAsConsumer ( final ClassScanner classScanner ) { classScanner . registerEntryConsumer ( classPathEntry -> { if ( ! classPathEntry . isTypeSignatureInUse ( DB_TABLE_ANNOTATION_BYTES ) ) { return ; } final Class < ? > beanClass ; try { beanClass = classPathEntry . loadClass ( ) ; } catch ( ClassNotFoundException cnfex ) { throw new DbOomException ( "Entry class not found: " + classPathEntry . name ( ) , cnfex ) ; } if ( beanClass == null ) { return ; } final DbTable dbTable = beanClass . getAnnotation ( DbTable . class ) ; if ( dbTable == null ) { return ; } if ( registerAsEntities ) { dbEntityManager . registerEntity ( beanClass ) ; } else { dbEntityManager . registerType ( beanClass ) ; } } ) ; }


Input: Sets the number of random characters that will be appended to the { [CODESPLIT] public void setRandomDigestChars ( final int randomDigestChars ) { this . randomDigestChars = randomDigestChars ; if ( randomDigestChars == 0 ) { uniqueDigestKey = null ; } else { uniqueDigestKey = new RandomString ( ) . randomAlphaNumeric ( randomDigestChars ) ; } }


Input: Creates bundle file in bundleFolder / staplerPath . Only file object is created not the file content . [CODESPLIT] protected File createBundleFile ( final String bundleId ) { File folder = new File ( bundleFolder , staplerPath ) ; if ( ! folder . exists ( ) ) { folder . mkdirs ( ) ; } return new File ( folder , bundleId ) ; }


Input: Lookups for bundle file . [CODESPLIT] public File lookupBundleFile ( String bundleId ) { if ( ( mirrors != null ) && ( ! mirrors . isEmpty ( ) ) ) { String realBundleId = mirrors . remove ( bundleId ) ; if ( realBundleId != null ) { bundleId = realBundleId ; } } return createBundleFile ( bundleId ) ; }


Input: Locates gzipped version of bundle file . If gzip file does not exist it will be created . [CODESPLIT] public File lookupGzipBundleFile ( final File file ) throws IOException { String path = file . getPath ( ) + ZipUtil . GZIP_EXT ; File gzipFile = new File ( path ) ; if ( ! gzipFile . exists ( ) ) { if ( log . isDebugEnabled ( ) ) { log . debug ( "gzip bundle to " + path ) ; } ZipUtil . gzip ( file ) ; } return gzipFile ; }


Input: Registers new bundle that consist of provided list of source paths . Returns the real bundle id as provided one is just a temporary bundle id . [CODESPLIT] public synchronized String registerBundle ( final String contextPath , final String actionPath , final String tempBundleId , final String bundleContentType , final List < String > sources ) { if ( tempBundleId == null || sources . isEmpty ( ) ) { if ( strategy == Strategy . ACTION_MANAGED ) { // page does not include any resource source file actionBundles . put ( actionPath , StringPool . EMPTY ) ; } return null ; } // create unique digest from the collected sources String [ ] sourcesArray = sources . toArray ( new String [ 0 ] ) ; for ( int i = 0 , sourcesArrayLength = sourcesArray . length ; i < sourcesArrayLength ; i ++ ) { sourcesArray [ i ] = sourcesArray [ i ] . trim ( ) . toLowerCase ( ) ; } if ( sortResources ) { Arrays . sort ( sourcesArray ) ; } StringBand sb = new StringBand ( sourcesArray . length ) ; for ( String src : sourcesArray ) { sb . append ( src ) ; } String sourcesString = sb . toString ( ) ; String bundleId = createDigest ( sourcesString ) ; bundleId += ' ' + bundleContentType ; // bundle appears for the first time, create the bundle if ( strategy == Strategy . ACTION_MANAGED ) { actionBundles . put ( actionPath , bundleId ) ; mirrors . put ( tempBundleId , bundleId ) ; } try { createBundle ( contextPath , actionPath , bundleId , sources ) ; } catch ( IOException ioex ) { throw new HtmlStaplerException ( "Can't create bundle" , ioex ) ; } return bundleId ; }


Input: Creates digest i . e . bundle id from given string . Returned digest must be filename safe for all platforms . [CODESPLIT] protected String createDigest ( final String source ) { final DigestEngine digestEngine = DigestEngine . sha256 ( ) ; final byte [ ] bytes = digestEngine . digest ( CharUtil . toSimpleByteArray ( source ) ) ; String digest = Base32 . encode ( bytes ) ; if ( uniqueDigestKey != null ) { digest += uniqueDigestKey ; } return digest ; }


Input: Creates bundle file by loading resource files content . If bundle file already exist it will not be recreated! [CODESPLIT] protected void createBundle ( final String contextPath , final String actionPath , final String bundleId , final List < String > sources ) throws IOException { final File bundleFile = createBundleFile ( bundleId ) ; if ( bundleFile . exists ( ) ) { return ; } StringBand sb = new StringBand ( sources . size ( ) * 2 ) ; for ( String src : sources ) { if ( sb . length ( ) != 0 ) { sb . append ( StringPool . NEWLINE ) ; } String content ; if ( isExternalResource ( src ) ) { content = downloadString ( src ) ; } else { if ( ! downloadLocal ) { // load local resource from file system String localFile = webRoot ; if ( src . startsWith ( contextPath + ' ' ) ) { src = src . substring ( contextPath . length ( ) ) ; } if ( src . startsWith ( StringPool . SLASH ) ) { // absolute path localFile += src ; } else { // relative path localFile += ' ' + FileNameUtil . getPathNoEndSeparator ( actionPath ) + ' ' + src ; } // trim link parameters, if any int qmndx = localFile . indexOf ( ' ' ) ; if ( qmndx != - 1 ) { localFile = localFile . substring ( 0 , qmndx ) ; } try { content = FileUtil . readString ( localFile ) ; } catch ( IOException ioex ) { if ( notFoundExceptionEnabled ) { throw ioex ; } if ( log . isWarnEnabled ( ) ) { log . warn ( ioex . getMessage ( ) ) ; } content = null ; } } else { // download local resource String localUrl = localAddressAndPort ; if ( src . startsWith ( StringPool . SLASH ) ) { localUrl += contextPath + src ; } else { localUrl += contextPath + FileNameUtil . getPath ( actionPath ) + ' ' + src ; } content = downloadString ( localUrl ) ; } if ( content != null ) { if ( isCssResource ( src ) ) { content = fixCssRelativeUrls ( content , src ) ; } } } if ( content != null ) { content = onResourceContent ( content ) ; sb . append ( content ) ; } } FileUtil . writeString ( bundleFile , sb . toString ( ) ) ; if ( log . isInfoEnabled ( ) ) { log . info ( "Bundle created: " + bundleId ) ; } }


Input: Clears all settings and removes all created bundle files from file system . [CODESPLIT] public synchronized void reset ( ) { if ( strategy == Strategy . ACTION_MANAGED ) { actionBundles . clear ( ) ; mirrors . clear ( ) ; } final FindFile ff = new FindFile ( ) ; ff . includeDirs ( false ) ; ff . searchPath ( new File ( bundleFolder , staplerPath ) ) ; File f ; int count = 0 ; while ( ( f = ff . nextFile ( ) ) != null ) { f . delete ( ) ; count ++ ; } if ( log . isInfoEnabled ( ) ) { log . info ( "reset: " + count + " bundle files deleted." ) ; } }


Input: Returns the content with all relative URLs fixed . [CODESPLIT] protected String fixCssRelativeUrls ( final String content , final String src ) { final String path = FileNameUtil . getPath ( src ) ; final Matcher matcher = CSS_URL_PATTERN . matcher ( content ) ; final StringBuilder sb = new StringBuilder ( content . length ( ) ) ; int start = 0 ; while ( matcher . find ( ) ) { sb . append ( content , start , matcher . start ( ) ) ; final String matchedUrl = StringUtil . removeChars ( matcher . group ( 1 ) , "'\"" ) ; final String url ; if ( matchedUrl . startsWith ( "https://" ) || matchedUrl . startsWith ( "http://" ) || matchedUrl . startsWith ( "data:" ) ) { url = "url('" + matchedUrl + "')" ; } else { url = fixRelativeUrl ( matchedUrl , path ) ; } sb . append ( url ) ; start = matcher . end ( ) ; } sb . append ( content . substring ( start ) ) ; return sb . toString ( ) ; }


Input: For a given URL ( optionally quoted ) produces CSS URL where relative paths are fixed and prefixed with offsetPath . [CODESPLIT] protected String fixRelativeUrl ( final String url , final String offsetPath ) { final StringBuilder res = new StringBuilder ( ) ; res . append ( "url('" ) ; if ( ! url . startsWith ( StringPool . SLASH ) ) { res . append ( "../" ) . append ( offsetPath ) ; } res . append ( url ) . append ( "')" ) ; return res . toString ( ) ; }


Input: Creates UPDATE query that updates all non - null values of an entity that is matched by id . [CODESPLIT] public DbSqlBuilder update ( final Object entity ) { String tableRef = createTableRefName ( entity ) ; if ( ! dbOomConfig . isUpdateAcceptsTableAlias ( ) ) { tableRef = null ; } return sql ( ) . $ ( UPDATE ) . table ( entity , tableRef ) . set ( tableRef , entity ) . $ ( WHERE ) . matchIds ( tableRef , entity ) ; }


Input: Creates UPDATE query that updates all values of an entity that is matched by id . [CODESPLIT] public DbSqlBuilder updateAll ( final Object entity ) { String tableRef = createTableRefName ( entity ) ; if ( ! dbOomConfig . isUpdateAcceptsTableAlias ( ) ) { tableRef = null ; } return sql ( ) . $ ( UPDATE ) . table ( entity , tableRef ) . setAll ( tableRef , entity ) . $ ( WHERE ) . matchIds ( tableRef , entity ) ; }


Input: Creates UPDATE query for single column of an entity that is matched by id . [CODESPLIT] public DbSqlBuilder updateColumn ( final Object entity , final String columnRef , final Object value ) { String tableRef = createTableRefName ( entity ) ; if ( ! dbOomConfig . isUpdateAcceptsTableAlias ( ) ) { tableRef = null ; } return sql ( ) . $ ( UPDATE ) . table ( entity , tableRef ) . $ ( SET ) . ref ( null , columnRef ) . $ ( EQUALS ) . columnValue ( value ) . $ ( WHERE ) . matchIds ( tableRef , entity ) ; }


Input: Reads property value and updates the DB . [CODESPLIT] public DbSqlBuilder updateColumn ( final Object entity , final String columnRef ) { final Object value = BeanUtil . pojo . getProperty ( entity , columnRef ) ; return updateColumn ( entity , columnRef , value ) ; }


Input: Creates DELETE query that deletes entity matched by non - null values . [CODESPLIT] public DbSqlBuilder delete ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( DELETE_FROM ) . table ( entity , null , tableRef ) . $ ( WHERE ) . match ( tableRef , entity ) ; }


Input: Creates DELETE query that deletes entity matched by all values . [CODESPLIT] public DbSqlBuilder deleteByAll ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( DELETE_FROM ) . table ( entity , null , tableRef ) . $ ( WHERE ) . matchAll ( tableRef , entity ) ; }


Input: Creates DELETE query that deletes entity by ID . [CODESPLIT] public DbSqlBuilder deleteById ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( DELETE_FROM ) . table ( entity , null , tableRef ) . $ ( WHERE ) . matchIds ( tableRef , entity ) ; }


Input: Creates DELETE query that deletes entity by ID . [CODESPLIT] public DbSqlBuilder deleteById ( final Object entityType , final Object id ) { final String tableRef = createTableRefName ( entityType ) ; return sql ( ) . $ ( DELETE_FROM ) . table ( entityType , null , tableRef ) . $ ( WHERE ) . refId ( tableRef ) . $ ( EQUALS ) . columnValue ( id ) ; }


Input: Creates SELECT criteria for the entity matched by non - null values . [CODESPLIT] public DbSqlBuilder find ( final Class target , final Object matchEntity ) { final String tableRef = createTableRefName ( target ) ; return sql ( ) . $ ( SELECT ) . column ( tableRef ) . $ ( FROM ) . table ( target , tableRef ) . $ ( WHERE ) . match ( tableRef , matchEntity ) ; }


Input: Creates SELECT criteria for the entity matched by non - null values . [CODESPLIT] public DbSqlBuilder find ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( SELECT ) . column ( tableRef ) . $ ( FROM ) . table ( entity , tableRef ) . $ ( WHERE ) . match ( tableRef , entity ) ; }


Input: Creates SELECT criteria for the entity matched by all values . [CODESPLIT] public DbSqlBuilder findByAll ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( SELECT ) . column ( tableRef ) . $ ( FROM ) . table ( entity , tableRef ) . $ ( WHERE ) . matchAll ( tableRef , entity ) ; }


Input: Creates SELECT criteria for the entity matched by column name [CODESPLIT] public DbSqlBuilder findByColumn ( final Class entity , final String column , final Object value ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( SELECT ) . column ( tableRef ) . $ ( FROM ) . table ( entity , tableRef ) . $ ( WHERE ) . ref ( tableRef , column ) . $ ( EQUALS ) . columnValue ( value ) ; }


Input: Creates SELECT criteria for the entity matched by foreign key . Foreign key is created by concatenating foreign table name and column name . [CODESPLIT] public DbSqlBuilder findForeign ( final Class entity , final Object value ) { final String tableRef = createTableRefName ( entity ) ; final DbEntityDescriptor dedFk = entityManager . lookupType ( value . getClass ( ) ) ; final String tableName = dbOomConfig . getTableNames ( ) . convertTableNameToEntityName ( dedFk . getTableName ( ) ) ; final String columnName = dbOomConfig . getColumnNames ( ) . convertColumnNameToPropertyName ( dedFk . getIdColumnName ( ) ) ; final String fkColumn = uncapitalize ( tableName ) + capitalize ( columnName ) ; final Object idValue = BeanUtil . pojo . getProperty ( value , dedFk . getIdPropertyName ( ) ) ; return sql ( ) . $ ( SELECT ) . column ( tableRef ) . $ ( FROM ) . table ( entity , tableRef ) . $ ( WHERE ) . ref ( tableRef , fkColumn ) . $ ( EQUALS ) . columnValue ( idValue ) ; }


Input: Returns all records for given type . [CODESPLIT] public DbSqlBuilder findAll ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( SELECT ) . column ( tableRef ) . $ ( FROM ) . table ( entity , tableRef ) ; }


Input: Creates SELECT criteria for the entity matched by id . [CODESPLIT] public DbSqlBuilder findById ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( SELECT ) . column ( tableRef ) . $ ( FROM ) . table ( entity , tableRef ) . $ ( WHERE ) . matchIds ( tableRef , entity ) ; }


Input: Creates SELECT criteria for the entity matched by id . [CODESPLIT] public DbSqlBuilder findById ( final Object entityType , final Object id ) { final String tableRef = createTableRefName ( entityType ) ; return sql ( ) . $ ( SELECT ) . column ( tableRef ) . $ ( FROM ) . table ( entityType , tableRef ) . $ ( WHERE ) . refId ( tableRef ) . $ ( EQUALS ) . columnValue ( id ) ; }


Input: Creates SELECT COUNT criteria for the entity matched by non - null values . [CODESPLIT] public DbSqlBuilder count ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( SELECT_COUNT_1_FROM ) . table ( entity , tableRef ) . $ ( WHERE ) . match ( tableRef , entity ) ; }


Input: Creates SELECT COUNT all query . [CODESPLIT] public DbSqlBuilder count ( final Class entityType ) { final String tableRef = createTableRefName ( entityType ) ; return sql ( ) . $ ( SELECT_COUNT_1_FROM ) . table ( entityType , tableRef ) ; }


Input: Creates SELECT COUNT criteria for the entity matched by all values . [CODESPLIT] public DbSqlBuilder countAll ( final Object entity ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( SELECT_COUNT_1_FROM ) . table ( entity , tableRef ) . $ ( WHERE ) . matchAll ( tableRef , entity ) ; }


Input: Creates UPDATE that increases / decreases column by some delta value . [CODESPLIT] public DbSqlBuilder increaseColumn ( final Class entity , final Object id , final String columnRef , final Number delta , final boolean increase ) { final String tableRef = createTableRefName ( entity ) ; return sql ( ) . $ ( UPDATE ) . table ( entity , null , tableRef ) . $ ( SET ) . ref ( null , columnRef ) . $ ( EQUALS ) . ref ( null , columnRef ) . $ ( increase ? StringPool . PLUS : StringPool . DASH ) . columnValue ( delta ) . $ ( WHERE ) . refId ( tableRef ) . $ ( EQUALS ) . columnValue ( id ) ; }


Input: Creates table reference name from entity type . Always appends an underscore to reference name in order to circumvent SQL compatibility issues when entity class name equals to a reserved word . [CODESPLIT] protected static String createTableRefName ( final Object entity ) { Class type = entity . getClass ( ) ; type = ( type == Class . class ? ( Class ) entity : type ) ; return ( type . getSimpleName ( ) + ' ' ) ; }


Input: Returns session from JTX transaction manager and started transaction . [CODESPLIT] @ Override public DbSession getDbSession ( ) { log . debug ( "Requesting db TX manager session" ) ; final DbJtxTransaction jtx = ( DbJtxTransaction ) jtxTxManager . getTransaction ( ) ; if ( jtx == null ) { throw new DbSqlException ( "No transaction is in progress and DbSession can't be provided. " + "It seems that transaction manager is not used to begin a transaction." ) ; } return jtx . requestResource ( ) ; }


Input: Resolves method name of method reference . Argument is used so { [CODESPLIT] public String ref ( final Object dummy ) { if ( dummy != null ) { if ( dummy instanceof String ) { return ( String ) dummy ; } throw new MethrefException ( "Target method not collected" ) ; } return ref ( ) ; }


Input: Returns name of method reference . Target { [CODESPLIT] public String ref ( ) { if ( instance == null ) { return null ; } try { Field f = instance . getClass ( ) . getDeclaredField ( "$__methodName$0" ) ; f . setAccessible ( true ) ; Object name = f . get ( instance ) ; if ( name == null ) { throw new MethrefException ( "Target method not collected" ) ; } return name . toString ( ) ; } catch ( Exception ex ) { if ( ex instanceof MethrefException ) { throw ( ( MethrefException ) ex ) ; } throw new MethrefException ( "Methref field not found" , ex ) ; } }


Input: Registers actions and applies proxetta on actions that are not already registered . We need to define { [CODESPLIT] @ Override public synchronized ActionRuntime registerAction ( Class actionClass , final Method actionMethod , ActionDefinition actionDefinition ) { if ( proxettaSupplier == null ) { return super . registerAction ( actionClass , actionMethod , actionDefinition ) ; } if ( actionDefinition == null ) { actionDefinition = actionMethodParser . parseActionDefinition ( actionClass , actionMethod ) ; } // create proxy for action class if not already created Class existing = proxyActionClasses . get ( actionClass ) ; if ( existing == null ) { final Proxetta proxetta = proxettaSupplier . get ( ) ; existing = proxetta . proxy ( ) . setTarget ( actionClass ) . define ( ) ; proxyActionClasses . put ( actionClass , existing ) ; } actionClass = existing ; return super . registerAction ( actionClass , actionMethod , actionDefinition ) ; }


Input: Creates an array with single element . [CODESPLIT] protected T [ ] convertToSingleElementArray ( final Object value ) { T [ ] singleElementArray = createArray ( 1 ) ; singleElementArray [ 0 ] = convertType ( value ) ; return singleElementArray ; }


Input: Converts non - array value to array . Detects various collection types and iterates them to make conversion and to create target array . [CODESPLIT] protected T [ ] convertValueToArray ( final Object value ) { if ( value instanceof Collection ) { Collection collection = ( Collection ) value ; T [ ] target = createArray ( collection . size ( ) ) ; int i = 0 ; for ( Object element : collection ) { target [ i ] = convertType ( element ) ; i ++ ; } return target ; } if ( value instanceof Iterable ) { Iterable iterable = ( Iterable ) value ; List < T > list = new ArrayList <> ( ) ; for ( Object element : iterable ) { list . add ( convertType ( element ) ) ; } T [ ] target = createArray ( list . size ( ) ) ; return list . toArray ( target ) ; } if ( value instanceof CharSequence ) { String [ ] strings = convertStringToArray ( value . toString ( ) ) ; return convertArrayToArray ( strings ) ; } // everything else: return convertToSingleElementArray ( value ) ; }


Input: Converts primitive array to target array . [CODESPLIT] @ SuppressWarnings ( "AutoBoxing" ) protected T [ ] convertPrimitiveArrayToArray ( final Object value , final Class primitiveComponentType ) { T [ ] result = null ; if ( primitiveComponentType == int . class ) { int [ ] array = ( int [ ] ) value ; result = createArray ( array . length ) ; for ( int i = 0 ; i < array . length ; i ++ ) { result [ i ] = convertType ( array [ i ] ) ; } } else if ( primitiveComponentType == long . class ) { long [ ] array = ( long [ ] ) value ; result = createArray ( array . length ) ; for ( int i = 0 ; i < array . length ; i ++ ) { result [ i ] = convertType ( array [ i ] ) ; } } else if ( primitiveComponentType == float . class ) { float [ ] array = ( float [ ] ) value ; result = createArray ( array . length ) ; for ( int i = 0 ; i < array . length ; i ++ ) { result [ i ] = convertType ( array [ i ] ) ; } } else if ( primitiveComponentType == double . class ) { double [ ] array = ( double [ ] ) value ; result = createArray ( array . length ) ; for ( int i = 0 ; i < array . length ; i ++ ) { result [ i ] = convertType ( array [ i ] ) ; } } else if ( primitiveComponentType == short . class ) { short [ ] array = ( short [ ] ) value ; result = createArray ( array . length ) ; for ( int i = 0 ; i < array . length ; i ++ ) { result [ i ] = convertType ( array [ i ] ) ; } } else if ( primitiveComponentType == byte . class ) { byte [ ] array = ( byte [ ] ) value ; result = createArray ( array . length ) ; for ( int i = 0 ; i < array . length ; i ++ ) { result [ i ] = convertType ( array [ i ] ) ; } } else if ( primitiveComponentType == char . class ) { char [ ] array = ( char [ ] ) value ; result = createArray ( array . length ) ; for ( int i = 0 ; i < array . length ; i ++ ) { result [ i ] = convertType ( array [ i ] ) ; } } else if ( primitiveComponentType == boolean . class ) { boolean [ ] array = ( boolean [ ] ) value ; result = createArray ( array . length ) ; for ( int i = 0 ; i < array . length ; i ++ ) { result [ i ] = convertType ( array [ i ] ) ; } } return result ; }


Input: Parses signature for generic information and returns a map where key is generic name and value is raw type . Returns an empty map if signature does not define any generics . [CODESPLIT] public Map < String , String > parseSignatureForGenerics ( final String signature , final boolean isInterface ) { if ( signature == null ) { return Collections . emptyMap ( ) ; } final Map < String , String > genericsMap = new HashMap <> ( ) ; SignatureReader sr = new SignatureReader ( signature ) ; StringBuilder sb = new StringBuilder ( ) ; TraceSignatureVisitor v = new TraceSignatureVisitor ( sb , isInterface ) { String genericName ; @ Override public void visitFormalTypeParameter ( final String name ) { genericName = name ; super . visitFormalTypeParameter ( name ) ; } @ Override public void visitClassType ( final String name ) { if ( genericName != null ) { genericsMap . put ( genericName , ' ' + name + ' ' ) ; genericName = null ; } super . visitClassType ( name ) ; } } ; sr . accept ( v ) ; return genericsMap ; }


Input: Resolves all collections for given type . [CODESPLIT] public SetInjectionPoint [ ] resolve ( final Class type , final boolean autowire ) { ClassDescriptor cd = ClassIntrospector . get ( ) . lookup ( type ) ; List < SetInjectionPoint > list = new ArrayList <> ( ) ; PropertyDescriptor [ ] allProperties = cd . getAllPropertyDescriptors ( ) ; for ( PropertyDescriptor propertyDescriptor : allProperties ) { if ( propertyDescriptor . isGetterOnly ( ) ) { continue ; } Class propertyType = propertyDescriptor . getType ( ) ; if ( ! ClassUtil . isTypeOf ( propertyType , Collection . class ) ) { continue ; } MethodDescriptor writeMethodDescriptor = propertyDescriptor . getWriteMethodDescriptor ( ) ; FieldDescriptor fieldDescriptor = propertyDescriptor . getFieldDescriptor ( ) ; PetiteInject ref = null ; if ( writeMethodDescriptor != null ) { ref = writeMethodDescriptor . getMethod ( ) . getAnnotation ( PetiteInject . class ) ; } if ( ref == null && fieldDescriptor != null ) { ref = fieldDescriptor . getField ( ) . getAnnotation ( PetiteInject . class ) ; } if ( ( ! autowire ) && ( ref == null ) ) { continue ; } list . add ( new SetInjectionPoint ( propertyDescriptor ) ) ; } SetInjectionPoint [ ] fields ; if ( list . isEmpty ( ) ) { fields = SetInjectionPoint . EMPTY ; } else { fields = list . toArray ( new SetInjectionPoint [ 0 ] ) ; } return fields ; }


Input: Returns <code > true< / code > if object has been already processed during the serialization . Used to prevent circular dependencies . Objects are matched by identity . [CODESPLIT] public boolean pushValue ( final Object value ) { for ( int i = 0 ; i < bagSize ; i ++ ) { JsonValueContext valueContext = bag . get ( i ) ; if ( valueContext . getValue ( ) == value ) { return true ; } } if ( bagSize == bag . size ( ) ) { lastValueContext = new JsonValueContext ( value ) ; bag . add ( lastValueContext ) ; } else { lastValueContext = bag . get ( bagSize ) ; lastValueContext . reuse ( value ) ; } bagSize ++ ; return false ; }


Input: { [CODESPLIT] @ Override public void pushName ( final String name , final boolean withComma ) { JsonValueContext valueContext = peekValueContext ( ) ; if ( valueContext != null ) { valueContext . setPropertyName ( name ) ; } super . pushName ( name , withComma ) ; }


Input: { [CODESPLIT] @ Override public void writeComma ( ) { JsonValueContext valueContext = peekValueContext ( ) ; if ( valueContext != null ) { valueContext . incrementIndex ( ) ; } super . writeComma ( ) ; }


Input: Serializes the object using { [CODESPLIT] public boolean serialize ( final Object object ) { if ( object == null ) { write ( NULL ) ; return true ; } TypeJsonSerializer typeJsonSerializer = null ; // callback if ( serializerResolver != null ) { typeJsonSerializer = serializerResolver . apply ( object ) ; } if ( typeJsonSerializer == null ) { // + read paths map if ( jsonSerializer . pathSerializersMap != null ) { typeJsonSerializer = jsonSerializer . pathSerializersMap . get ( path ) ; } final Class type = object . getClass ( ) ; // + read local types map if ( jsonSerializer . typeSerializersMap != null ) { typeJsonSerializer = jsonSerializer . typeSerializersMap . lookup ( type ) ; } // + globals if ( typeJsonSerializer == null ) { typeJsonSerializer = TypeJsonSerializerMap . get ( ) . lookup ( type ) ; } } return typeJsonSerializer . serialize ( this , object ) ; }


Input: Matches property types that are ignored by default . [CODESPLIT] public boolean matchIgnoredPropertyTypes ( final Class propertyType , final boolean excludeMaps , final boolean include ) { if ( ! include ) { return false ; } if ( propertyType != null ) { if ( ! jsonSerializer . deep ) { ClassDescriptor propertyTypeClassDescriptor = ClassIntrospector . get ( ) . lookup ( propertyType ) ; if ( propertyTypeClassDescriptor . isArray ( ) ) { return false ; } if ( propertyTypeClassDescriptor . isCollection ( ) ) { return false ; } if ( excludeMaps ) { if ( propertyTypeClassDescriptor . isMap ( ) ) { return false ; } } } // still not excluded, continue with excluded types and type names // + excluded types if ( jsonSerializer . excludedTypes != null ) { for ( Class excludedType : jsonSerializer . excludedTypes ) { if ( ClassUtil . isTypeOf ( propertyType , excludedType ) ) { return false ; } } } // + exclude type names final String propertyTypeName = propertyType . getName ( ) ; if ( jsonSerializer . excludedTypeNames != null ) { for ( String excludedTypeName : jsonSerializer . excludedTypeNames ) { if ( Wildcard . match ( propertyTypeName , excludedTypeName ) ) { return false ; } } } } return true ; }


Input: Closes current session and all allocated resources . All attached queries are closed . If a transaction is still active exception occurs . Database connection is returned to the { [CODESPLIT] public void closeSession ( ) { log . debug ( "Closing db session" ) ; SQLException sqlException = null ; if ( queries != null ) { for ( DbQueryBase query : queries ) { SQLException sex = query . closeQuery ( ) ; if ( sex != null ) { if ( sqlException == null ) { sqlException = sex ; } else { sqlException . setNextException ( sex ) ; } } } } if ( connection != null ) { if ( txActive ) { throw new DbSqlException ( "TX was not closed before closing the session" ) ; } connectionProvider . closeConnection ( connection ) ; connection = null ; } queries = null ; if ( sqlException != null ) { throw new DbSqlException ( "Closing DbSession failed" , sqlException ) ; } }


Input: Opens connection in auto - commit mode if already not opened . [CODESPLIT] protected void openConnectionForQuery ( ) { if ( connection == null ) { connection = connectionProvider . getConnection ( ) ; txActive = false ; // txAction should already be false try { connection . setAutoCommit ( true ) ; } catch ( SQLException sex ) { throw new DbSqlException ( "Failed to open non-TX connection" , sex ) ; } } }


Input: Opens a transaction . [CODESPLIT] protected void openTx ( ) { if ( connection == null ) { connection = connectionProvider . getConnection ( ) ; } txActive = true ; try { connection . setAutoCommit ( false ) ; if ( txMode . getIsolation ( ) != DbTransactionMode . ISOLATION_DEFAULT ) { connection . setTransactionIsolation ( txMode . getIsolation ( ) ) ; } connection . setReadOnly ( txMode . isReadOnly ( ) ) ; } catch ( SQLException sex ) { throw new DbSqlException ( "Open TX failed" , sex ) ; } }


Input: Closes current transaction . [CODESPLIT] protected void closeTx ( ) { txActive = false ; try { connection . setAutoCommit ( true ) ; } catch ( SQLException sex ) { throw new DbSqlException ( "Close TX failed" , sex ) ; } }


Input: Commit the current transaction writing any unflushed changes to the database . Transaction mode is closed . [CODESPLIT] public void commitTransaction ( ) { log . debug ( "Committing transaction" ) ; assertTxIsActive ( ) ; try { connection . commit ( ) ; } catch ( SQLException sex ) { throw new DbSqlException ( "Commit TX failed" , sex ) ; } finally { closeTx ( ) ; } }


Input: Roll back the current transaction . Transaction mode is closed . [CODESPLIT] public void rollbackTransaction ( ) { log . debug ( "Rolling-back transaction" ) ; assertTxIsActive ( ) ; try { connection . rollback ( ) ; } catch ( SQLException sex ) { throw new DbSqlException ( "Rollback TX failed" , sex ) ; } finally { closeTx ( ) ; } }


Input: Replaces action path macros in the path . If one of the provided paths is <code > null< / code > it will not be replaced - so to emphasize the problem . [CODESPLIT] protected String replaceActionNameMacros ( String path , final ActionNames actionNames ) { final String packageName = actionNames . packageName ( ) ; final String className = actionNames . className ( ) ; final String methodName = actionNames . methodName ( ) ; final String httpMethod = actionNames . httpMethod ( ) ; if ( packageName != null ) { path = StringUtil . replace ( path , PACKAGE_MACRO , packageName ) ; } if ( className != null ) { path = StringUtil . replace ( path , CLASS_MACRO , className ) ; } if ( methodName != null ) { path = StringUtil . replace ( path , METHOD_MACRO , methodName ) ; } if ( httpMethod != null ) { path = StringUtil . replace ( path , HTTPMETHOD_MACRO , httpMethod ) ; } return path ; }


Input: Single point of { [CODESPLIT] protected ActionDefinition createActionDef ( String path , String httpMethod , String resultBasePath , final ActionNames actionNames ) { path = replaceActionNameMacros ( path , actionNames ) ; if ( httpMethod != null ) { httpMethod = replaceActionNameMacros ( httpMethod , actionNames ) ; } if ( resultBasePath != null ) { resultBasePath = replaceActionNameMacros ( resultBasePath , actionNames ) ; } return new ActionDefinition ( path , httpMethod , resultBasePath ) ; }


Input: Returns { [CODESPLIT] protected boolean isAbsolutePath ( final String path ) { if ( path == null ) { return false ; } return path . startsWith ( StringPool . SLASH ) ; }


Input: Create properties from the file . [CODESPLIT] public static Properties createFromFile ( final File file ) throws IOException { Properties prop = new Properties ( ) ; loadFromFile ( prop , file ) ; return prop ; }


Input: Loads properties from the file . Properties are appended to the existing properties object . [CODESPLIT] public static void loadFromFile ( final Properties p , final String fileName ) throws IOException { loadFromFile ( p , new File ( fileName ) ) ; }


Input: Loads properties from the file . Properties are appended to the existing properties object . [CODESPLIT] public static void loadFromFile ( final Properties p , final File file ) throws IOException { FileInputStream fis = null ; try { fis = new FileInputStream ( file ) ; p . load ( fis ) ; } finally { StreamUtil . close ( fis ) ; } }


Input: Writes properties to a file . [CODESPLIT] public static void writeToFile ( final Properties p , final String fileName ) throws IOException { writeToFile ( p , new File ( fileName ) , null ) ; }


Input: Writes properties to a file . [CODESPLIT] public static void writeToFile ( final Properties p , final String fileName , final String header ) throws IOException { writeToFile ( p , new File ( fileName ) , header ) ; }


Input: Writes properties to a file . [CODESPLIT] public static void writeToFile ( final Properties p , final File file ) throws IOException { writeToFile ( p , file , null ) ; }


Input: Writes properties to a file . [CODESPLIT] public static void writeToFile ( final Properties p , final File file , final String header ) throws IOException { FileOutputStream fos = null ; try { fos = new FileOutputStream ( file ) ; p . store ( fos , header ) ; } finally { StreamUtil . close ( fos ) ; } }


Input: Creates properties from string . [CODESPLIT] public static Properties createFromString ( final String data ) throws IOException { Properties p = new Properties ( ) ; loadFromString ( p , data ) ; return p ; }


Input: Loads properties from string . [CODESPLIT] public static void loadFromString ( final Properties p , final String data ) throws IOException { try ( ByteArrayInputStream is = new ByteArrayInputStream ( data . getBytes ( StringPool . ISO_8859_1 ) ) ) { p . load ( is ) ; } }


Input: Creates new Properties object from the original one by copying those properties that have specified first part of the key name . Prefix may be optionally stripped during this process . [CODESPLIT] public static Properties subset ( final Properties p , String prefix , final boolean stripPrefix ) { if ( StringUtil . isBlank ( prefix ) ) { return p ; } if ( ! prefix . endsWith ( StringPool . DOT ) ) { prefix += ' ' ; } Properties result = new Properties ( ) ; int baseLen = prefix . length ( ) ; for ( Object o : p . keySet ( ) ) { String key = ( String ) o ; if ( key . startsWith ( prefix ) ) { result . setProperty ( stripPrefix ? key . substring ( baseLen ) : key , p . getProperty ( key ) ) ; } } return result ; }


Input: Creates properties from classpath . [CODESPLIT] public static Properties createFromClasspath ( final String ... rootTemplate ) { Properties p = new Properties ( ) ; return loadFromClasspath ( p , rootTemplate ) ; }


Input: Loads properties from classpath file ( s ) . Properties are specified using wildcards . [CODESPLIT] public static Properties loadFromClasspath ( final Properties p , final String ... rootTemplate ) { ClassScanner . create ( ) . registerEntryConsumer ( entryData -> UncheckedException . runAndWrapException ( ( ) -> p . load ( entryData . openInputStream ( ) ) ) ) . includeResources ( true ) . ignoreException ( true ) . excludeAllEntries ( true ) . includeEntries ( rootTemplate ) . scanDefaultClasspath ( ) ; return p ; }


Input: Returns String property from a map . If key is not found or if value is not a String returns <code > null< / code > . Mimics <code > Property . getProperty< / code > but on map . [CODESPLIT] public static String getProperty ( final Map map , final String key ) { return getProperty ( map , key , null ) ; }


Input: Returns String property from a map . [CODESPLIT] public static String getProperty ( final Map map , final String key , final String defaultValue ) { Object val = map . get ( key ) ; return ( val instanceof String ) ? ( String ) val : defaultValue ; }


Input: Resolves all variables . [CODESPLIT] public static void resolveAllVariables ( final Properties prop ) { for ( Object o : prop . keySet ( ) ) { String key = ( String ) o ; String value = resolveProperty ( prop , key ) ; prop . setProperty ( key , value ) ; } }


Input: Returns property with resolved variables . [CODESPLIT] public static String resolveProperty ( final Map map , final String key ) { String value = getProperty ( map , key ) ; if ( value == null ) { return null ; } value = stp . parse ( value , macroName -> getProperty ( map , macroName ) ) ; return value ; }


Input: Resolves tx scope from scope pattern . [CODESPLIT] public String resolveScope ( final Class type , final String methodName ) { if ( scopePattern == null ) { return null ; } String ctx = scopePattern ; ctx = StringUtil . replace ( ctx , JTXCTX_PATTERN_CLASS , type . getName ( ) ) ; ctx = StringUtil . replace ( ctx , JTXCTX_PATTERN_METHOD , methodName ) ; return ctx ; }


Input: Reads transaction mode from method annotation . Annotations are cached for better performances . [CODESPLIT] public synchronized JtxTransactionMode getTxMode ( final Class type , final String methodName , final Class [ ] methodArgTypes , final String unique ) { String signature = type . getName ( ) + ' ' + methodName + ' ' + unique ; JtxTransactionMode txMode = txmap . get ( signature ) ; if ( txMode == null ) { if ( ! txmap . containsKey ( signature ) ) { final Method m ; try { m = type . getMethod ( methodName , methodArgTypes ) ; } catch ( NoSuchMethodException nsmex ) { throw new ProxettaException ( nsmex ) ; } final TransactionAnnotationValues txAnn = readTransactionAnnotation ( m ) ; if ( txAnn != null ) { txMode = new JtxTransactionMode ( txAnn . propagation ( ) , txAnn . isolation ( ) , txAnn . readOnly ( ) , txAnn . timeout ( ) ) ; } else { txMode = defaultTransactionMode ; } txmap . put ( signature , txMode ) ; } } return txMode ; }


Input: Registers new TX annotations . [CODESPLIT] @ SuppressWarnings ( { "unchecked" } ) public void registerAnnotations ( final Class < ? extends Annotation > [ ] annotations ) { this . annotations = annotations ; this . annotationParsers = new AnnotationParser [ annotations . length ] ; for ( int i = 0 ; i < annotations . length ; i ++ ) { annotationParsers [ i ] = TransactionAnnotationValues . parserFor ( annotations [ i ] ) ; } }


Input: Finds TX annotation . [CODESPLIT] protected TransactionAnnotationValues readTransactionAnnotation ( final Method method ) { for ( AnnotationParser annotationParser : annotationParsers ) { TransactionAnnotationValues tad = TransactionAnnotationValues . of ( annotationParser , method ) ; if ( tad != null ) { return tad ; } } return null ; }


Input: ---------------------------------------------------------------- attributes [CODESPLIT] public void addIdSelector ( String id ) { id = unescape ( id ) ; selectors . add ( new AttributeSelector ( ID , EQUALS , id ) ) ; }


Input: Accepts single node . [CODESPLIT] @ Override public boolean accept ( final Node node ) { // match element name with node name if ( ! matchElement ( node ) ) { return false ; } // match attributes int totalSelectors = selectorsCount ( ) ; for ( int i = 0 ; i < totalSelectors ; i ++ ) { Selector selector = getSelector ( i ) ; // just attr name existence switch ( selector . getType ( ) ) { case ATTRIBUTE : if ( ! ( ( AttributeSelector ) selector ) . accept ( node ) ) { return false ; } break ; case PSEUDO_CLASS : if ( ! ( ( PseudoClassSelector ) selector ) . accept ( node ) ) { return false ; } break ; case PSEUDO_FUNCTION : if ( ! ( ( PseudoFunctionSelector ) selector ) . accept ( node ) ) { return false ; } break ; } } return true ; }


Input: Matches element to css selector . All non - element types are ignored . [CODESPLIT] protected boolean matchElement ( final Node node ) { if ( node . getNodeType ( ) != Node . NodeType . ELEMENT ) { return false ; } String element = getElement ( ) ; String nodeName = node . getNodeName ( ) ; return element . equals ( StringPool . STAR ) || element . equals ( nodeName ) ; }


Input: Accepts node within current results . [CODESPLIT] public boolean accept ( final List < Node > currentResults , final Node node , final int index ) { // match attributes int totalSelectors = selectorsCount ( ) ; for ( int i = 0 ; i < totalSelectors ; i ++ ) { Selector selector = getSelector ( i ) ; // just attr name existence switch ( selector . getType ( ) ) { case PSEUDO_FUNCTION : if ( ! ( ( PseudoFunctionSelector ) selector ) . accept ( currentResults , node , index ) ) { return false ; } break ; case PSEUDO_CLASS : if ( ! ( ( PseudoClassSelector ) selector ) . accept ( currentResults , node , index ) ) { return false ; } break ; default : } } return true ; }


Input: Unescapes CSS string by removing all backslash characters from it . [CODESPLIT] protected String unescape ( final String value ) { if ( value . indexOf ( ' ' ) == - 1 ) { return value ; } return StringUtil . remove ( value , ' ' ) ; }


Input: Builds a set of java core packages . [CODESPLIT] private String [ ] buildJrePackages ( final int javaVersionNumber ) { final ArrayList < String > packages = new ArrayList <> ( ) ; switch ( javaVersionNumber ) { case 9 : case 8 : case 7 : case 6 : case 5 : // in Java1.5, the apache stuff moved packages . add ( "com.sun.org.apache" ) ; // fall through... case 4 : if ( javaVersionNumber == 4 ) { packages . add ( "org.apache.crimson" ) ; packages . add ( "org.apache.xalan" ) ; packages . add ( "org.apache.xml" ) ; packages . add ( "org.apache.xpath" ) ; } packages . add ( "org.ietf.jgss" ) ; packages . add ( "org.w3c.dom" ) ; packages . add ( "org.xml.sax" ) ; // fall through... case 3 : packages . add ( "org.omg" ) ; packages . add ( "com.sun.corba" ) ; packages . add ( "com.sun.jndi" ) ; packages . add ( "com.sun.media" ) ; packages . add ( "com.sun.naming" ) ; packages . add ( "com.sun.org.omg" ) ; packages . add ( "com.sun.rmi" ) ; packages . add ( "sunw.io" ) ; packages . add ( "sunw.util" ) ; // fall through... case 2 : packages . add ( "com.sun.java" ) ; packages . add ( "com.sun.image" ) ; // fall through... case 1 : default : // core stuff packages . add ( "sun" ) ; packages . add ( "java" ) ; packages . add ( "javax" ) ; break ; } return packages . toArray ( new String [ 0 ] ) ; }


Input: ---------------------------------------------------------------- java checks [CODESPLIT] private int detectJavaVersionNumber ( ) { String javaVersion = JAVA_VERSION ; final int lastDashNdx = javaVersion . lastIndexOf ( ' ' ) ; if ( lastDashNdx != - 1 ) { javaVersion = javaVersion . substring ( 0 , lastDashNdx ) ; } if ( javaVersion . startsWith ( "1." ) ) { // up to java 8 final int index = javaVersion . indexOf ( ' ' , 2 ) ; return Integer . parseInt ( javaVersion . substring ( 2 , index ) ) ; } else { final int index = javaVersion . indexOf ( ' ' ) ; return Integer . parseInt ( index == - 1 ? javaVersion : javaVersion . substring ( 0 , index ) ) ; } }


Input: Copies all non - final values to the empty cloned object . Cache - related values are not copied . [CODESPLIT] protected < T extends Node > T cloneTo ( final T dest ) { //		dest.nodeValue = nodeValue;		// already  in clone implementations! dest . parentNode = parentNode ; if ( attributes != null ) { dest . attributes = new ArrayList <> ( attributes . size ( ) ) ; for ( int i = 0 , attributesSize = attributes . size ( ) ; i < attributesSize ; i ++ ) { Attribute attr = attributes . get ( i ) ; dest . attributes . add ( attr . clone ( ) ) ; } } if ( childNodes != null ) { dest . childNodes = new ArrayList <> ( childNodes . size ( ) ) ; for ( int i = 0 , childNodesSize = childNodes . size ( ) ; i < childNodesSize ; i ++ ) { Node child = childNodes . get ( i ) ; Node childClone = child . clone ( ) ; childClone . parentNode = dest ; // fix parent! dest . childNodes . add ( childClone ) ; } } return dest ; }


Input: Removes this node from DOM tree . [CODESPLIT] public void detachFromParent ( ) { if ( parentNode == null ) { return ; } if ( parentNode . childNodes != null ) { parentNode . childNodes . remove ( siblingIndex ) ; parentNode . reindexChildren ( ) ; } parentNode = null ; }


Input: Appends child node . Don t use this node in the loop since it might be slow due to { [CODESPLIT] public void addChild ( final Node node ) { node . detachFromParent ( ) ; node . parentNode = this ; initChildNodes ( node ) ; childNodes . add ( node ) ; reindexChildrenOnAdd ( 1 ) ; }


Input: Appends several child nodes at once . Reindex is done only once after all children are added . [CODESPLIT] public void addChild ( final Node ... nodes ) { if ( nodes . length == 0 ) { return ; // nothing to add } for ( Node node : nodes ) { node . detachFromParent ( ) ; node . parentNode = this ; initChildNodes ( node ) ; childNodes . add ( node ) ; } reindexChildrenOnAdd ( nodes . length ) ; }


Input: Inserts node at given index . [CODESPLIT] public void insertChild ( final Node node , final int index ) { node . detachFromParent ( ) ; node . parentNode = this ; try { initChildNodes ( node ) ; childNodes . add ( index , node ) ; } catch ( IndexOutOfBoundsException ignore ) { throw new LagartoDOMException ( "Invalid node index: " + index ) ; } reindexChildren ( ) ; }


Input: Inserts node before provided node . [CODESPLIT] public void insertBefore ( final Node newChild , final Node refChild ) { int siblingIndex = refChild . getSiblingIndex ( ) ; refChild . parentNode . insertChild ( newChild , siblingIndex ) ; }


Input: Inserts several child nodes before provided node . [CODESPLIT] public void insertBefore ( final Node [ ] newChilds , final Node refChild ) { if ( newChilds . length == 0 ) { return ; } int siblingIndex = refChild . getSiblingIndex ( ) ; refChild . parentNode . insertChild ( newChilds , siblingIndex ) ; }


Input: Inserts node after provided node . [CODESPLIT] public void insertAfter ( final Node newChild , final Node refChild ) { int siblingIndex = refChild . getSiblingIndex ( ) + 1 ; if ( siblingIndex == refChild . parentNode . getChildNodesCount ( ) ) { refChild . parentNode . addChild ( newChild ) ; } else { refChild . parentNode . insertChild ( newChild , siblingIndex ) ; } }


Input: Inserts several child nodes after referent node . [CODESPLIT] public void insertAfter ( final Node [ ] newChilds , final Node refChild ) { if ( newChilds . length == 0 ) { return ; } int siblingIndex = refChild . getSiblingIndex ( ) + 1 ; if ( siblingIndex == refChild . parentNode . getChildNodesCount ( ) ) { refChild . parentNode . addChild ( newChilds ) ; } else { refChild . parentNode . insertChild ( newChilds , siblingIndex ) ; } }


Input: Removes child node at given index . Returns removed node or <code > null< / code > if index is invalid . [CODESPLIT] public Node removeChild ( final int index ) { if ( childNodes == null ) { return null ; } Node node ; try { node = childNodes . get ( index ) ; } catch ( IndexOutOfBoundsException ignore ) { return null ; } node . detachFromParent ( ) ; return node ; }


Input: Removes all child nodes . Each child node will be detached from this parent . [CODESPLIT] public void removeAllChilds ( ) { List < Node > removedNodes = childNodes ; childNodes = null ; childElementNodes = null ; childElementNodesCount = 0 ; if ( removedNodes != null ) { for ( int i = 0 , removedNodesSize = removedNodes . size ( ) ; i < removedNodesSize ; i ++ ) { Node removedNode = removedNodes . get ( i ) ; removedNode . detachFromParent ( ) ; } } }


Input: Returns attribute at given index or <code > null< / code > if index not found . [CODESPLIT] public Attribute getAttribute ( final int index ) { if ( attributes == null ) { return null ; } if ( ( index < 0 ) || ( index >= attributes . size ( ) ) ) { return null ; } return attributes . get ( index ) ; }


Input: Returns <code > true< / code > if node contains an attribute . [CODESPLIT] public boolean hasAttribute ( String name ) { if ( attributes == null ) { return false ; } if ( ! ownerDocument . config . isCaseSensitive ( ) ) { name = name . toLowerCase ( ) ; } for ( int i = 0 , attributesSize = attributes . size ( ) ; i < attributesSize ; i ++ ) { Attribute attr = attributes . get ( i ) ; if ( attr . getName ( ) . equals ( name ) ) { return true ; } } return false ; }


Input: Returns attribute value . Returns <code > null< / code > when attribute doesn t exist or when attribute exist but doesn t specify a value . [CODESPLIT] public String getAttribute ( final String name ) { Attribute attribute = getAttributeInstance ( name ) ; if ( attribute == null ) { return null ; } return attribute . getValue ( ) ; }


Input: Sets attribute value . Value may be <code > null< / code > . [CODESPLIT] public void setAttribute ( String name , final String value ) { initAttributes ( ) ; String rawAttributeName = name ; if ( ! ownerDocument . config . isCaseSensitive ( ) ) { name = name . toLowerCase ( ) ; } // search if attribute with the same name exist for ( int i = 0 , attributesSize = attributes . size ( ) ; i < attributesSize ; i ++ ) { Attribute attr = attributes . get ( i ) ; if ( attr . getName ( ) . equals ( name ) ) { attr . setValue ( value ) ; return ; } } attributes . add ( new Attribute ( rawAttributeName , name , value ) ) ; }


Input: Returns <code > true< / code > if attribute containing some word . [CODESPLIT] public boolean isAttributeContaining ( final String name , final String word ) { Attribute attr = getAttributeInstance ( name ) ; if ( attr == null ) { return false ; } return attr . isContaining ( word ) ; }


Input: Finds the first child node with given node name . [CODESPLIT] public Node findChildNodeWithName ( final String name ) { if ( childNodes == null ) { return null ; } for ( final Node childNode : childNodes ) { if ( childNode . getNodeName ( ) . equals ( name ) ) { return childNode ; } } return null ; }


Input: Filters child nodes . [CODESPLIT] public Node [ ] filterChildNodes ( final Predicate < Node > nodePredicate ) { if ( childNodes == null ) { return new Node [ 0 ] ; } return childNodes . stream ( ) . filter ( nodePredicate ) . toArray ( Node [ ] :: new ) ; }


Input: Returns a child node at given index or <code > null< / code > if child doesn t exist for that index . [CODESPLIT] public Node getChild ( final int index ) { if ( childNodes == null ) { return null ; } if ( ( index < 0 ) || ( index >= childNodes . size ( ) ) ) { return null ; } return childNodes . get ( index ) ; }


Input: Returns a child node with given hierarchy . Just a shortcut for successive calls of { [CODESPLIT] public Node getChild ( final int ... indexes ) { Node node = this ; for ( int index : indexes ) { node = node . getChild ( index ) ; } return node ; }


Input: Returns a child element node at given index . If index is out of bounds <code > null< / code > is returned . [CODESPLIT] public Element getChildElement ( final int index ) { initChildElementNodes ( ) ; if ( ( index < 0 ) || ( index >= childElementNodes . length ) ) { return null ; } return childElementNodes [ index ] ; }


Input: Returns first child or <code > null< / code > if no children exist . [CODESPLIT] public Node getFirstChild ( ) { if ( childNodes == null ) { return null ; } if ( childNodes . isEmpty ( ) ) { return null ; } return childNodes . get ( 0 ) ; }


Input: Returns last child or <code > null< / code > if no children exist . [CODESPLIT] public Node getLastChild ( ) { if ( childNodes == null ) { return null ; } if ( childNodes . isEmpty ( ) ) { return null ; } return childNodes . get ( getChildNodesCount ( ) - 1 ) ; }


Input: Returns last child <b > element< / b > with given name or <code > null< / code > if no such child node exist . [CODESPLIT] public Element getLastChildElement ( final String elementName ) { if ( childNodes == null ) { return null ; } int from = childNodes . size ( ) - 1 ; for ( int i = from ; i >= 0 ; i -- ) { Node child = childNodes . get ( i ) ; if ( child . getNodeType ( ) == NodeType . ELEMENT && elementName . equals ( child . getNodeName ( ) ) ) { child . initSiblingNames ( ) ; return ( Element ) child ; } } return null ; }


Input: Checks the health of child nodes . Useful during complex tree manipulation to check if everything is OK . Not optimized for speed should be used just for testing purposes . [CODESPLIT] public boolean check ( ) { if ( childNodes == null ) { return true ; } // children int siblingElementIndex = 0 ; for ( int i = 0 , childNodesSize = childNodes . size ( ) ; i < childNodesSize ; i ++ ) { Node childNode = childNodes . get ( i ) ; if ( childNode . siblingIndex != i ) { return false ; } if ( childNode . getNodeType ( ) == NodeType . ELEMENT ) { if ( childNode . siblingElementIndex != siblingElementIndex ) { return false ; } siblingElementIndex ++ ; } } if ( childElementNodesCount != siblingElementIndex ) { return false ; } // child element nodes if ( childElementNodes != null ) { if ( childElementNodes . length != childElementNodesCount ) { return false ; } int childCount = getChildNodesCount ( ) ; for ( int i = 0 ; i < childCount ; i ++ ) { Node child = getChild ( i ) ; if ( child . siblingElementIndex >= 0 ) { if ( childElementNodes [ child . siblingElementIndex ] != child ) { return false ; } } } } // sibling names if ( siblingNameIndex != - 1 ) { List < Node > siblings = parentNode . childNodes ; int index = 0 ; for ( int i = 0 , siblingsSize = siblings . size ( ) ; i < siblingsSize ; i ++ ) { Node sibling = siblings . get ( i ) ; if ( sibling . siblingNameIndex == - 1 && nodeType == NodeType . ELEMENT && nodeName . equals ( sibling . getNodeName ( ) ) ) { if ( sibling . siblingNameIndex != index ++ ) { return false ; } } } } // process children for ( Node childNode : childNodes ) { if ( ! childNode . check ( ) ) { return false ; } } return true ; }


Input: Reindex children nodes . Must be called on every children addition / removal . Iterates { [CODESPLIT] protected void reindexChildren ( ) { int siblingElementIndex = 0 ; for ( int i = 0 , childNodesSize = childNodes . size ( ) ; i < childNodesSize ; i ++ ) { Node childNode = childNodes . get ( i ) ; childNode . siblingIndex = i ; childNode . siblingNameIndex = - 1 ; // reset sibling name info if ( childNode . getNodeType ( ) == NodeType . ELEMENT ) { childNode . siblingElementIndex = siblingElementIndex ; siblingElementIndex ++ ; } } childElementNodesCount = siblingElementIndex ; childElementNodes = null ; // reset child element nodes }


Input: Initializes list of child elements . [CODESPLIT] protected void initChildElementNodes ( ) { if ( childElementNodes == null ) { childElementNodes = new Element [ childElementNodesCount ] ; int childCount = getChildNodesCount ( ) ; for ( int i = 0 ; i < childCount ; i ++ ) { Node child = getChild ( i ) ; if ( child . siblingElementIndex >= 0 ) { childElementNodes [ child . siblingElementIndex ] = ( Element ) child ; } } } }


Input: Initializes siblings elements of the same name . [CODESPLIT] protected void initSiblingNames ( ) { if ( siblingNameIndex == - 1 ) { List < Node > siblings = parentNode . childNodes ; int index = 0 ; for ( int i = 0 , siblingsSize = siblings . size ( ) ; i < siblingsSize ; i ++ ) { Node sibling = siblings . get ( i ) ; if ( sibling . siblingNameIndex == - 1 && nodeType == NodeType . ELEMENT && nodeName . equals ( sibling . getNodeName ( ) ) ) { sibling . siblingNameIndex = index ++ ; } } } }


Input: Initializes child nodes list when needed . Also fix owner document for new node if needed . [CODESPLIT] protected void initChildNodes ( final Node newNode ) { if ( childNodes == null ) { childNodes = new ArrayList <> ( ) ; } if ( ownerDocument != null ) { if ( newNode . ownerDocument != ownerDocument ) { changeOwnerDocument ( newNode , ownerDocument ) ; } } }


Input: Changes owner document for given node and all its children . [CODESPLIT] protected void changeOwnerDocument ( final Node node , final Document ownerDocument ) { node . ownerDocument = ownerDocument ; int childCount = node . getChildNodesCount ( ) ; for ( int i = 0 ; i < childCount ; i ++ ) { Node child = node . getChild ( i ) ; changeOwnerDocument ( child , ownerDocument ) ; } }


Input: Returns this node s next sibling of <b > any< / b > type or <code > null< / code > if this is the last sibling . [CODESPLIT] public Node getNextSibling ( ) { List < Node > siblings = parentNode . childNodes ; int index = siblingIndex + 1 ; if ( index >= siblings . size ( ) ) { return null ; } return siblings . get ( index ) ; }


Input: Returns this node s next <b > element< / b > . [CODESPLIT] public Node getNextSiblingElement ( ) { parentNode . initChildElementNodes ( ) ; if ( siblingElementIndex == - 1 ) { int max = parentNode . getChildNodesCount ( ) ; for ( int i = siblingIndex ; i < max ; i ++ ) { Node sibling = parentNode . childNodes . get ( i ) ; if ( sibling . getNodeType ( ) == NodeType . ELEMENT ) { return sibling ; } } return null ; } int index = siblingElementIndex + 1 ; if ( index >= parentNode . childElementNodesCount ) { return null ; } return parentNode . childElementNodes [ index ] ; }