001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2010-2011 ApexIdentity Inc.
015 * Portions Copyright 2011-2015 ForgeRock AS.
016 */
017
018package org.forgerock.openig.resolver;
019
020import java.lang.reflect.Array;
021
022/**
023 * Resolves native arrays of objects.
024 */
025public class ArrayResolver implements Resolver {
026
027    /**
028     * Returns {@code null}, as arrays are not resolved through type discovery.
029     *
030     * @return {@code null}, as arrays are not resolved through type discovery.
031     */
032    @Override
033    public Class<?> getKey() {
034        return null; // special resolver, doesn't need index
035    }
036
037    @Override
038    public Object get(Object object, Object element) {
039        if (element instanceof Number) {
040            int index = ((Number) element).intValue();
041            try {
042                if (object instanceof Object[]) {
043                    // for array of objects
044                    return ((Object[]) object)[index];
045                } else if (object.getClass().isArray()) {
046                    // for array of primitives
047                    return Array.get(object, index);
048                }
049            } catch (IndexOutOfBoundsException ioobe) {
050                // cannot resolve index
051            }
052        }
053        return Resolver.UNRESOLVED;
054    }
055
056    @Override
057    public Object put(Object object, Object element, Object value) {
058        // get original value first
059        Object original = get(object, element);
060        if (original != Resolver.UNRESOLVED && element instanceof Number) {
061            int index = ((Number) element).intValue();
062            try {
063                if (object instanceof Object[]) {
064                    // for array of objects
065                    ((Object[]) object)[index] = value;
066                } else if (object.getClass().isArray()) {
067                    // for array of primitives
068                    Array.set(object, index, value);
069                }
070                return original;
071            } catch (ArrayStoreException | IndexOutOfBoundsException | IllegalArgumentException e) {
072                // cannot resolve index
073            }
074        }
075        return Resolver.UNRESOLVED;
076    }
077}