Package org.apache.jackrabbit.ocm.manager.collectionconverter.impl

Source Code of org.apache.jackrabbit.ocm.manager.collectionconverter.impl.ResidualPropertiesCollectionConverterImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.jackrabbit.ocm.manager.collectionconverter.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.ValueFormatException;

import org.apache.jackrabbit.ocm.exception.ObjectContentManagerException;
import org.apache.jackrabbit.ocm.manager.atomictypeconverter.AtomicTypeConverter;
import org.apache.jackrabbit.ocm.manager.collectionconverter.ManageableCollection;
import org.apache.jackrabbit.ocm.manager.collectionconverter.ManageableCollectionUtil;
import org.apache.jackrabbit.ocm.manager.objectconverter.ObjectConverter;
import org.apache.jackrabbit.ocm.mapper.Mapper;
import org.apache.jackrabbit.ocm.mapper.model.CollectionDescriptor;
import org.apache.jackrabbit.ocm.reflection.ReflectionUtils;

/**
* The <code>ResidualPropertiesCollectionConverterImpl</code> is a collection
* converter for multiple properties accessed through
* Node.getProperties(String pattern).
*
* @author <a href="mailto:fmeschbe[at]apache[dot]com">Felix Meschberger</a>
*/
public class ResidualPropertiesCollectionConverterImpl extends
        AbstractCollectionConverterImpl {
   
    /**
     * Constructor
     *
     * @param atomicTypeConverters
     * @param objectConverter
     * @param mapper
     */
    public ResidualPropertiesCollectionConverterImpl(Map atomicTypeConverters,
        ObjectConverter objectConverter, Mapper mapper) {
        super(atomicTypeConverters, objectConverter, mapper);
    }

    /**
     *
     * @see AbstractCollectionConverterImpl#doInsertCollection(Session, Node, CollectionDescriptor, ManageableCollection)
     */
    protected void doInsertCollection(Session session, Node parentNode,
        CollectionDescriptor collectionDescriptor,
        ManageableCollection collection) throws RepositoryException {
        internalSetProperties(session, parentNode, collectionDescriptor,
            collection, false);
    }

    /**
     *
     * @see AbstractCollectionConverterImpl#doUpdateCollection(Session, Node, CollectionDescriptor, ManageableCollection)
     */
    protected void doUpdateCollection(Session session, Node parentNode,
        CollectionDescriptor collectionDescriptor,
        ManageableCollection collection) throws RepositoryException {
        internalSetProperties(session, parentNode, collectionDescriptor,
            collection, true);
    }

    /**
     * @see AbstractCollectionConverterImpl#doGetCollection(Session, Node, CollectionDescriptor, Class)
     */
    protected ManageableCollection doGetCollection(Session session,
        Node parentNode, CollectionDescriptor collectionDescriptor,
        Class collectionFieldClass) throws RepositoryException {
        try {
            String jcrName = getCollectionJcrName(collectionDescriptor);
            PropertyIterator pi = parentNode.getProperties(jcrName);
            if (!pi.hasNext()) {
                return null;
            }

            ManageableCollection collection = ManageableCollectionUtil.getManageableCollection(collectionFieldClass);
            AtomicTypeConverter atomicTypeConverter = getAtomicTypeConverter(collectionDescriptor);

            while (pi.hasNext()) {
                Property prop = pi.nextProperty();

                // ignore protected properties here
                if (prop.getDefinition().isProtected()) {
                    continue;
                }

                // handle multvalues as a list
                Object value;
                if (prop.getDefinition().isMultiple()) {
                    List valueList = new ArrayList();
                    Value[] values = prop.getValues();
                    for (int i = 0; i < values.length; i++) {
                        valueList.add(atomicTypeConverter.getObject(values[i]));
                    }
                    value = valueList;
                } else {
                    value = atomicTypeConverter.getObject(prop.getValue());
                }

                if (collection instanceof Map) {
                    String name = prop.getName();
                    ((Map) collection).put(name, value);
                } else {
                    collection.addObject(value);
                }
            }

            return collection;
        } catch (ValueFormatException vfe) {
            throw new ObjectContentManagerException("Cannot get the collection field : "
                + collectionDescriptor.getFieldName() + "for class "
                + collectionDescriptor.getClassDescriptor().getClassName(), vfe);
        }
    }

    /**
     * @see AbstractCollectionConverterImpl#doIsNull(Session, Node, CollectionDescriptor, Class)
     */
    protected boolean doIsNull(Session session, Node parentNode,
            CollectionDescriptor collectionDescriptor, Class collectionFieldClass)
            throws RepositoryException {
        String jcrName = getCollectionJcrName(collectionDescriptor);
        return (parentNode == null || !parentNode.getProperties(jcrName).hasNext());
    }

    private void internalSetProperties(Session session, Node parentNode,
        CollectionDescriptor collectionDescriptor,
        ManageableCollection collection, boolean removeExisting)
        throws RepositoryException {

        String jcrName = getCollectionJcrName(collectionDescriptor);

        // can only persist maps, not general collections
        if (!(collection instanceof Map)) {
            return;
        }

        // Delete existing values - before checking for collection !
        if (removeExisting) {
            for (PropertyIterator pi = parentNode.getProperties(jcrName); pi.hasNext();) {
                Property prop = pi.nextProperty();
                if (!prop.getDefinition().isProtected()) {
                    prop.remove();
                }
            }
        }

        AtomicTypeConverter atomicTypeConverter = getAtomicTypeConverter(collectionDescriptor);

        try {
            Map map = (Map) collection;
            ValueFactory valueFactory = session.getValueFactory();
            for (Iterator ei = map.entrySet().iterator(); ei.hasNext();) {
                Map.Entry entry = (Map.Entry) ei.next();
                String name = String.valueOf(entry.getKey());
               
                // verify the property is not an existing protected property
                if (parentNode.hasProperty(name)
                    && parentNode.getProperty(name).getDefinition().isProtected()) {
                    continue;
                }
               
                Object value = entry.getValue();
                if (value instanceof List) {
                    // multi value
                    List valueList = (List) value;
                    Value[] jcrValues = new Value[valueList.size()];
                    int i = 0;
                    for (Iterator vi = valueList.iterator(); vi.hasNext();) {
                        value = vi.next();
                        jcrValues[i++] = atomicTypeConverter.getValue(
                            valueFactory, value);
                    }
                    parentNode.setProperty(name, jcrValues);
                } else {
                    // single value
                    Value jcrValue = atomicTypeConverter.getValue(valueFactory,
                        value);
                    parentNode.setProperty(name, jcrValue);
                }
            }
        } catch (ValueFormatException vfe) {
            throw new ObjectContentManagerException("Cannot insert collection field : "
                + collectionDescriptor.getFieldName() + " of class "
                + collectionDescriptor.getClassDescriptor().getClassName(), vfe);
        }
    }
   
    /**
     * Returns the AtomicTypeConverter for the element class of the described
     * collection. If no such converter can be found a ObjectContentManagerException
     * is thrown.
     *
     * @param collectionDescriptor The descriptor of the collection for whose
     *      elements an AtomicTypeConverter is requested.
     *     
     * @return The AtomicTypeConverter for the elements of the collection
     *
     * @throws ObjectContentManagerException if no such type converter is registered
     */
    private AtomicTypeConverter getAtomicTypeConverter(CollectionDescriptor collectionDescriptor) {
        String elementClassName = collectionDescriptor.getElementClassName();
        Class elementClass = ReflectionUtils.forName(elementClassName);
        AtomicTypeConverter atc = (AtomicTypeConverter) atomicTypeConverters.get(elementClass);
        if (atc != null) {
            return atc;
        }
       
        throw new ObjectContentManagerException(
            "Cannot get AtomicTypeConverter for element class "
                + elementClassName + " of class "
                + collectionDescriptor.getClassDescriptor().getClassName());
    }
}
TOP

Related Classes of org.apache.jackrabbit.ocm.manager.collectionconverter.impl.ResidualPropertiesCollectionConverterImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.