    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 *  Unless required by applicable law or agreed to in writing, software
    012 *  distributed under the License is distributed on an "AS IS" BASIS,
    013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 *  See the License for the specific language governing permissions and
    015 *  limitations under the License.
    016 */
    017package org.apache.bcel.generic;
    018
    019import java.io.DataOutputStream;
    020import java.io.IOException;
    021import java.util.ArrayList;
    022import java.util.List;
    023import java.util.stream.Collectors;
    024
    025import org.apache.bcel.classfile.ArrayElementValue;
    026import org.apache.bcel.classfile.ElementValue;
    027import org.apache.commons.lang3.stream.Streams;
    028
    029/**
    030 * @since 6.0
    031 */
    032public class ArrayElementValueGen extends ElementValueGen {
    033    // J5TODO: Should we make this an array or a list? A list would be easier to
    034    // modify ...
    035    private final List<ElementValueGen> evalues;
    036
    037    /**
    038     * @param value
    039     * @param cpool
    040     */
    041    public ArrayElementValueGen(final ArrayElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) {
    042        super(ARRAY, cpool);
    043        evalues = new ArrayList<>();
    044        final ElementValue[] in = value.getElementValuesArray();
    045        for (final ElementValue element : in) {
    046            evalues.add(ElementValueGen.copy(element, cpool, copyPoolEntries));
    047        }
    048    }
    049
    050    public ArrayElementValueGen(final ConstantPoolGen cp) {
    051        super(ARRAY, cp);
    052        evalues = new ArrayList<>();
    053    }
    054
    055    public ArrayElementValueGen(final int type, final ElementValue[] elementValues, final ConstantPoolGen cpool) {
    056        super(type, cpool);
    057        if (type != ARRAY) {
    058            throw new IllegalArgumentException("Only element values of type array can be built with this ctor - type specified: " + type);
    059        }
    060        this.evalues = Streams.of(elementValues).map(e -> ElementValueGen.copy(e, cpool, true)).collect(Collectors.toList());
    061    }
    062
    063    public void addElement(final ElementValueGen gen) {
    064        evalues.add(gen);
    065    }
    066
    067    @Override
    068    public void dump(final DataOutputStream dos) throws IOException {
    069        dos.writeByte(super.getElementValueType()); // u1 type of value (ARRAY == '[')
    070        dos.writeShort(evalues.size());
    071        for (final ElementValueGen element : evalues) {
    072            element.dump(dos);
    073        }
    074    }
    075
    076    /**
    077     * Return immutable variant of this ArrayElementValueGen
    078     */
    079    @Override
    080    public ElementValue getElementValue() {
    081        final ElementValue[] immutableData = new ElementValue[evalues.size()];
    082        int i = 0;
    083        for (final ElementValueGen element : evalues) {
    084            immutableData[i++] = element.getElementValue();
    085        }
    086        return new ArrayElementValue(super.getElementValueType(), immutableData, getConstantPool().getConstantPool());
    087    }
    088
    089    public List<ElementValueGen> getElementValues() {
    090        return evalues;
    091    }
    092
    093    public int getElementValuesSize() {
    094        return evalues.size();
    095    }
    096
    097    @Override
    098    public String stringifyValue() {
    099        final StringBuilder sb = new StringBuilder();
    100        sb.append("[");
    101        String comma = "";
    102        for (final ElementValueGen element : evalues) {
    103            sb.append(comma);
    104            comma = ",";
    105            sb.append(element.stringifyValue());
    106        }
    107        sb.append("]");
    108        return sb.toString();
    109    }
    110}