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.commons.flatfile.morph;
018
019import java.util.Locale;
020
021import org.apache.commons.flatfile.IndexedEntityCollection;
022
023import net.sf.morph.reflect.Reflector;
024import net.sf.morph.reflect.SizableReflector;
025import net.sf.morph.reflect.reflectors.ArrayReflector;
026import net.sf.morph.reflect.reflectors.CollectionReflector;
027import net.sf.morph.reflect.reflectors.EnumerationReflector;
028import net.sf.morph.reflect.reflectors.IteratorReflector;
029import net.sf.morph.reflect.reflectors.ListReflector;
030import net.sf.morph.reflect.reflectors.ObjectReflector;
031import net.sf.morph.reflect.reflectors.SetReflector;
032import net.sf.morph.reflect.reflectors.SimpleDelegatingReflector;
033import net.sf.morph.reflect.reflectors.SortedSetReflector;
034import net.sf.morph.transform.copiers.ContainerCopier;
035import net.sf.morph.transform.TransformationException;
036
037/**
038 * Copies containers to IndexedEntityCollections. Additionally recognizes <code>null</code> copy source as an empty
039 * collection.
040 * @version $Revision: 1301237 $ $Date: 2012-03-15 17:08:23 -0500 (Thu, 15 Mar 2012) $
041 */
042public class ContainerToIndexedEntityCollectionCopier extends ContainerCopier {
043    private static final Class<?>[] DEST_CLASSES = new Class[] { IndexedEntityCollection.class };
044
045    private static class SizeOneReflector extends ObjectReflector implements SizableReflector {
046        /**
047         * {@inheritDoc}
048         */
049        @Override
050        protected int getSizeImpl(Object container) throws Exception {
051            return 1;
052        }
053    }
054
055    /**
056     * Create a new ContainerToIndexedEntityCollectionCopier
057     */
058    public ContainerToIndexedEntityCollectionCopier() {
059        setReflector(new SimpleDelegatingReflector(new Reflector[] {
060                new EntityCollectionReflector(), new ListReflector(), new SortedSetReflector(),
061                new SetReflector(), new EnumerationReflector(), new IteratorReflector(),
062                new ArrayReflector(), new CollectionReflector(), new SizeOneReflector() }));
063    }
064
065    /**
066     * {@inheritDoc}
067     */
068    @Override
069    public synchronized void setSourceClasses(@SuppressWarnings("rawtypes") Class[] sourceClasses) {
070        super.setSourceClasses(sourceClasses);
071    }
072
073    /**
074     * {@inheritDoc}
075     */
076    @Override
077    protected Class<?>[] getSourceClassesImpl() throws Exception {
078        Class<?>[] c = getBeanReflector().getReflectableClasses();
079        Class<?>[] result = new Class[c.length + 1];
080        System.arraycopy(c, 0, result, 0, c.length);
081        return result;
082    }
083
084    /**
085     * {@inheritDoc}
086     */
087    @Override
088    public synchronized void setDestinationClasses(@SuppressWarnings("rawtypes") Class[] destinationClasses) {
089        super.setDestinationClasses(destinationClasses);
090    }
091
092    /**
093     * {@inheritDoc}
094     */
095    @Override
096    protected Class<?>[] getDestinationClassesImpl() throws Exception {
097        return DEST_CLASSES;
098    }
099
100    /**
101     * {@inheritDoc}
102     */
103    @Override
104    protected void copyImpl(Object destination, Object source, Locale locale,
105            Integer preferredTransformationType) throws TransformationException {
106        int size = source == null ? 0 : getBeanReflector().getSize(source);
107        ((IndexedEntityCollection) destination).setSize(size);
108        if (size > 0) {
109            super.copyImpl(destination, source, locale, preferredTransformationType);
110        }
111    }
112
113    /**
114     * {@inheritDoc}
115     */
116    @Override
117    protected boolean isAutomaticallyHandlingNulls() {
118        return false;
119    }
120}