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;
023
024import org.apache.bcel.classfile.ArrayElementValue;
025import org.apache.bcel.classfile.ElementValue;
026
027/**
028 * @since 6.0
029 */
030public class ArrayElementValueGen extends ElementValueGen {
031    // J5TODO: Should we make this an array or a list? A list would be easier to
032    // modify ...
033    private final List<ElementValueGen> evalues;
034
035    /**
036     * @param value
037     * @param cpool
038     */
039    public ArrayElementValueGen(final ArrayElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) {
040        super(ARRAY, cpool);
041        evalues = new ArrayList<>();
042        final ElementValue[] in = value.getElementValuesArray();
043        for (final ElementValue element : in) {
044            evalues.add(ElementValueGen.copy(element, cpool, copyPoolEntries));
045        }
046    }
047
048    public ArrayElementValueGen(final ConstantPoolGen cp) {
049        super(ARRAY, cp);
050        evalues = new ArrayList<>();
051    }
052
053    public ArrayElementValueGen(final int type, final ElementValue[] datums, final ConstantPoolGen cpool) {
054        super(type, cpool);
055        if (type != ARRAY) {
056            throw new IllegalArgumentException("Only element values of type array can be built with this ctor - type specified: " + type);
057        }
058        this.evalues = new ArrayList<>();
059        for (final ElementValue datum : datums) {
060            evalues.add(ElementValueGen.copy(datum, cpool, true));
061        }
062    }
063
064    public void addElement(final ElementValueGen gen) {
065        evalues.add(gen);
066    }
067
068    @Override
069    public void dump(final DataOutputStream dos) throws IOException {
070        dos.writeByte(super.getElementValueType()); // u1 type of value (ARRAY == '[')
071        dos.writeShort(evalues.size());
072        for (final ElementValueGen element : evalues) {
073            element.dump(dos);
074        }
075    }
076
077    /**
078     * Return immutable variant of this ArrayElementValueGen
079     */
080    @Override
081    public ElementValue getElementValue() {
082        final ElementValue[] immutableData = new ElementValue[evalues.size()];
083        int i = 0;
084        for (final ElementValueGen element : evalues) {
085            immutableData[i++] = element.getElementValue();
086        }
087        return new ArrayElementValue(super.getElementValueType(), immutableData, getConstantPool().getConstantPool());
088    }
089
090    public List<ElementValueGen> getElementValues() {
091        return evalues;
092    }
093
094    public int getElementValuesSize() {
095        return evalues.size();
096    }
097
098    @Override
099    public String stringifyValue() {
100        final StringBuilder sb = new StringBuilder();
101        sb.append("[");
102        String comma = "";
103        for (final ElementValueGen element : evalues) {
104            sb.append(comma);
105            comma = ",";
106            sb.append(element.stringifyValue());
107        }
108        sb.append("]");
109        return sb.toString();
110    }
111}