com.evolveum.midpoint.prism.xjc.AnyArrayList.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.prism.xjc.AnyArrayList.java

Source

/*
 * Copyright (c) 2010-2015 Evolveum
 *
 * 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 com.evolveum.midpoint.prism.xjc;

import java.util.AbstractList;
import java.util.Collection;

import javax.xml.namespace.QName;

import org.apache.commons.lang.Validate;

import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismContainerable;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.util.JAXBUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;

/**
 * A list used for JAXB getAny() methods.
 * It is not used for normal prism operation, not even if compilte-time (JAXB) classes are used.
 * It is quite a bad way to use getAny() methods from the JAXB classes, it is much better to use
 * prism facet instead. However we need this to be fully JAXB compliant and therefore support
 * XML marshalling/unmarshalling. This is important e.g. for JAX-WS.
 * 
 * @author Radovan Semancik
 */
public class AnyArrayList<C extends Containerable> extends AbstractList<Object> {

    private PrismContainerValue<C> containerValue;

    public AnyArrayList(PrismContainerValue<C> containerValue) {
        Validate.notNull(containerValue, "Container value must not be null.");
        this.containerValue = containerValue;
    }

    @Override
    public int size() {
        if (isSchemaless()) {
            if (containerValue.getRawElements() == null) {
                return 0;
            }
            return containerValue.getRawElements().size();
        } else {
            // Each item and each value are presented as one list entry
            // (multi-valued items are represented as multiple occurrences of the same element)
            int size = 0;
            if (containerValue.isEmpty()) {
                return size;
            }
            for (Item<?, ?> item : containerValue.getItems()) {
                size += item.getValues().size();
            }
            return size;
        }
    }

    @Override
    public Object get(int index) {
        if (isSchemaless()) {
            return containerValue.getRawElements().get(index);
        } else {
            if (containerValue != null) {
                for (Item<?, ?> item : containerValue.getItems()) {
                    if (index < item.getValues().size()) {
                        return asElement(item.getValue(index));
                    } else {
                        index -= item.getValues().size();
                    }
                }
                throw new IndexOutOfBoundsException();
            }
            return null; //TODO: is this OK??
        }
    }

    @Override
    public boolean addAll(Collection<? extends Object> elements) {
        Validate.notNull(elements, "Collection must not be null.");

        if (elements.isEmpty()) {
            return false;
        }

        for (Object element : elements) {
            add(element);
        }

        return true;
    }

    @Override
    public boolean addAll(int i, Collection<? extends Object> elements) {
        return addAll(elements);
    }

    @Override
    public boolean add(Object element) {
        try {
            return containerValue.addRawElement(element);
        } catch (SchemaException e) {
            QName elementName = JAXBUtil.getElementQName(element);
            throw new IllegalArgumentException("Element " + elementName
                    + " cannot be added because is violates object schema: " + e.getMessage(), e);
        }
    }

    @Override
    public void add(int i, Object element) {
        add(element);
    }

    @Override
    public Object remove(int index) {
        if (isSchemaless()) {
            return containerValue.getRawElements().remove(index);
        } else {
            for (Item<?, ?> item : containerValue.getItems()) {
                if (index < item.getValues().size()) {
                    item.remove(index);
                } else {
                    index -= item.getValues().size();
                }
            }
            throw new IndexOutOfBoundsException();
        }
    }

    @Override
    public boolean remove(Object element) {
        if (isSchemaless()) {
            return containerValue.removeRawElement(element);
        } else {
            try {
                return containerValue.deleteRawElement(element);
            } catch (SchemaException e) {
                QName elementName = JAXBUtil.getElementQName(element);
                throw new IllegalArgumentException("Element " + elementName
                        + " cannot be removed because is violates object schema: " + e.getMessage(), e);
            }
        }
    }

    @Override
    public boolean removeAll(Collection<?> objects) {
        boolean changed = false;
        for (Object object : objects) {
            if (!changed) {
                changed = remove(object);
            } else {
                remove(object);
            }
        }
        return changed;
    }

    private PrismContainerDefinition getDefinition() {
        PrismContainerable<C> parent = containerValue.getParent();
        if (parent == null) {
            return null;
        }
        return parent.getDefinition();
    }

    private boolean isSchemaless() {
        return getDefinition() == null;
    }

    private PrismContainer<C> getContainer() {
        return containerValue.getContainer();
    }

    private PrismContext getPrismContext() {
        return getContainer().getPrismContext();
    }

    private Object asElement(PrismValue itemValue) {
        PrismContext prismContext = containerValue.getPrismContext();
        if (prismContext == null) {
            throw new IllegalStateException("prismContext is null in " + containerValue);
        }
        try {
            return prismContext.getJaxbDomHack().toAny(itemValue);
        } catch (SchemaException e) {
            throw new SystemException("Unexpected schema problem: " + e.getMessage(), e);
        }
        // return itemValue.asDomElement();
    }

}