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 */ 017 package org.apache.commons.betwixt.io.read; 018 019 import java.util.ArrayList; 020 import java.util.Iterator; 021 022 /** 023 * <p>Chain implementation that's backed by a list. 024 * This is the default implementation used by Betwixt. 025 * </p><p> 026 * <strong>Note</strong> this implementation is <em>not</em> 027 * intended to allow multiple threads of execution to perform 028 * modification operations concurrently with traversal of the chain. 029 * Users who require this behaviour are advised to create their own implementation. 030 * </p> 031 * 032 * @author Robert Burrell Donkin 033 * @since 0.5 034 */ 035 public class BeanCreationList extends BeanCreationChain { 036 037 //-------------------------------------------------------- Class Methods 038 039 /** 040 * Creates the default <code>BeanCreationChain</code> used when reading beans. 041 * @return a <code>BeanCreationList</code> with the default creators loader in order, not null 042 */ 043 public static final BeanCreationList createStandardChain() { 044 BeanCreationList chain = new BeanCreationList(); 045 chain.addBeanCreator( ChainedBeanCreatorFactory.createIDREFBeanCreator() ); 046 chain.addBeanCreator( ChainedBeanCreatorFactory.createDerivedBeanCreator() ); 047 chain.addBeanCreator( ChainedBeanCreatorFactory.createElementTypeBeanCreator() ); 048 return chain; 049 } 050 051 052 053 //-------------------------------------------------------- Attributes 054 /** The list backing this chain */ 055 private ArrayList beanCreators = new ArrayList(); 056 057 //-------------------------------------------------------- Methods 058 059 /** 060 * Creates an Object based on the given element mapping and read context. 061 * Delegates to chain. 062 * 063 * @param elementMapping the element mapping details 064 * @param readContext create against this context 065 * @return the created bean, possibly null 066 */ 067 public Object create( ElementMapping elementMapping, ReadContext readContext ) { 068 ChainWorker worker = new ChainWorker(); 069 return worker.create( elementMapping, readContext ); 070 } 071 072 //-------------------------------------------------------- Properties 073 074 /** 075 * Gets the number of BeanCreators in the wrapped chain. 076 * @return the number of <code>ChainedBeanCreator</code>'s in the current chain 077 */ 078 public int getSize() { 079 return beanCreators.size(); 080 } 081 082 /** 083 * Inserts a <code>BeanCreator</code> at the given position in the chain. 084 * Shifts the object currently in that position - and any subsequent elements - 085 * to the right. 086 * 087 * @param index index at which the creator should be inserted 088 * @param beanCreator the <code>BeanCreator</code> to be inserted, not null 089 * @throws IndexOutOfBoundsException if the index is out of the range 090 * <code>(index < 0 || index > getSize()) 091 */ 092 public void insertBeanCreator( 093 int index, 094 ChainedBeanCreator beanCreator ) 095 throws IndexOutOfBoundsException { 096 beanCreators.add( index, beanCreator ); 097 } 098 099 /** 100 * Adds a <code>BeanCreator</code> to the end of the chain. 101 * @param beanCreator the <code>BeanCreator</code> to be inserted, not null 102 */ 103 public void addBeanCreator( ChainedBeanCreator beanCreator ) { 104 beanCreators.add( beanCreator ); 105 } 106 107 /** 108 * Clears the creator chain. 109 */ 110 public void clearBeanCreators() { 111 beanCreators.clear(); 112 } 113 114 /** Worker class walks a chain */ 115 private class ChainWorker extends BeanCreationChain { 116 /** Iterator for the creator list */ 117 private Iterator iterator; 118 /** Creates the iterator */ 119 ChainWorker() { 120 iterator = beanCreators.iterator(); 121 } 122 123 /** 124 * @see BeanCreationChain#create 125 */ 126 public Object create( ElementMapping elementMapping, ReadContext readContext ) { 127 if ( iterator.hasNext() ) { 128 ChainedBeanCreator beanCreator = (ChainedBeanCreator) iterator.next(); 129 return beanCreator.create( elementMapping, readContext, this ); 130 } 131 132 return null; 133 } 134 } 135 }