/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.config.java.internal.parsing.asm;

import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.createMutableAnnotation;
import static org.springframework.util.ClassUtils.getDefaultClassLoader;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.ArrayList;

import org.springframework.asm.AnnotationVisitor;


/** TODO: JAVADOC */
class MutableAnnotationArrayVisitor extends AnnotationAdapter {
    private final ArrayList<Object> values = new ArrayList<Object>();
    private final MutableAnnotation mutableAnno;
    private final String attribName;

    public MutableAnnotationArrayVisitor(MutableAnnotation mutableAnno, String attribName) {
        super(AsmUtils.EMPTY_VISITOR);

        this.mutableAnno = mutableAnno;
        this.attribName = attribName;
    }

    @Override
    public void visit(String na, Object value) {
        values.add(value);
    }

    @Override
    public AnnotationVisitor visitAnnotation(String na, String annoTypeDescriptor) {
        String annoTypeName = AsmUtils.convertTypeDescriptorToClassName(annoTypeDescriptor);
        try {
            @SuppressWarnings("unchecked")
            Class<? extends Annotation> annoType =
                (Class<? extends Annotation>) getDefaultClassLoader().loadClass(annoTypeName);
            Object anno = createMutableAnnotation(annoType);
            values.add(anno);
            return new MutableAnnotationVisitor((MutableAnnotation) anno);
        } catch (Exception e) { throw new AsmParsingException(e); }
    }

    @Override
    public void visitEnd() {
        Class<?> arrayType = mutableAnno.getAttributeType(attribName);
        Object[] array = (Object[])Array.newInstance(arrayType.getComponentType(), 0);
        mutableAnno.setAttributeValue(attribName, values.toArray(array));
    }

}
