View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.flatfile;
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.List;
23  
24  /**
25   * Entity collection with the following approach:  a size (number of children)
26   * and a prototypical child are assigned.  The prototype child is cloned
27   * <code>size</code> times, and these clones become the indexed child entities.
28   */
29  public class EntityArray extends EntityCollectionSupport implements
30          IndexedEntityCollection {
31      private static final long serialVersionUID = 8716199462287161060L;
32  
33      private int size = -1;
34      private int minimumSize = 0;
35      private int maximumSize = Integer.MAX_VALUE;
36      private boolean resizable = false;
37      private List<Entity> children;
38      private Entity prototype;
39  
40      /**
41       * Create a new EntityArray.
42       */
43      public EntityArray() {
44          // default constructor
45      }
46  
47      /**
48       * Create a new IndexedEntityCollection.
49       * @param size number of occurrences of the prototypical Entity
50       */
51      public EntityArray(int size) {
52          setSize(size);
53      }
54  
55      /**
56       * Create a new EntityArray with the specified prototype.
57       * @param prototype Entity
58       */
59      public EntityArray(Entity prototype) {
60          setPrototype(prototype);
61      }
62  
63      /**
64       * Create a new IndexedEntityCollection.
65       * @param prototype Entity
66       * @param size number of occurrences
67       */
68      public EntityArray(Entity prototype, int size) {
69          this(prototype);
70          setSize(size);
71      }
72  
73      /**
74       * {@inheritDoc}
75       */
76      public Entity getChild(int index) {
77          initialize();
78          return (Entity) children.get(index);
79      }
80  
81      /**
82       * {@inheritDoc}
83       */
84      public synchronized Collection<Entity> getChildren() {
85          initialize();
86          return Collections.unmodifiableCollection(children);
87      }
88  
89      /**
90       * Get the prototype.
91       * @return Entity.
92       */
93      public synchronized Entity getPrototype() {
94          return prototype;
95      }
96  
97      /**
98       * Set the prototype.
99       * @param prototype The Entity prototype to set.
100      */
101     public synchronized void setPrototype(Entity prototype) {
102         if (prototype == null) {
103             throw new IllegalArgumentException("prototype Entity was null");
104         }
105         this.prototype = prototype;
106     }
107 
108     /**
109      * {@inheritDoc}
110      * @throws IllegalArgumentException if <code>size</code> is not valid.
111      */
112     public synchronized void setSize(int size) {
113         if (this.size >= 0 && !isResizable()) {
114             if (size == this.size()) {
115                 return;
116             }
117             throw new IllegalStateException("size already set");
118         }
119         if (size < minimumSize || size > maximumSize) {
120             throw new IllegalArgumentException("illegal collection size: "
121                     + size + "; should be <= " + maximumSize + " and >= "
122                     + minimumSize);
123         }
124         this.size = size;
125     }
126 
127     /**
128      * {@inheritDoc}
129      */
130     public synchronized int size() {
131         return size;
132     }
133 
134     /**
135      * {@inheritDoc}
136      */
137     public synchronized boolean isSizable() {
138         return size == -1 || isResizable();
139     }
140 
141     /**
142      * Clone this EntityArray.
143      * @return new EntityArray
144      */
145     @Override
146     public synchronized EntityArray clone() {
147         EntityArray result = (EntityArray) super.clone();
148         if (children != null) {
149             result.children = new ArrayList<Entity>();
150             for (Entity e : children) {
151                 result.children.add(e.clone());
152             }
153         }
154         return result;
155     }
156 
157     /**
158      * Initialize this EntityArray.
159      */
160     private synchronized void initialize() {
161         if (children != null) {
162             return;
163         }
164         if (size < 0) {
165             throw new IllegalStateException("EntityArray size not set");
166         }
167         if (size == 0) {
168             children = Collections.<Entity>emptyList();
169             return;
170         }
171         if (prototype == null) {
172             throw new IllegalStateException("Prototype child entity not set");
173         }
174         children = new ArrayList<Entity>(size);
175         adjustSize();
176     }
177 
178     /**
179      * Adjust the size of this EntityArray.
180      */
181     private synchronized void adjustSize() {
182         if (children.size() > size) {
183             children.subList(size, children.size()).clear();
184             return;
185         }
186         for (int i = children.size(); i < size; i++) {
187             children.add(prototype.clone());
188         }
189     }
190 
191     /**
192      * Get the int maximumSize.
193      * @return int
194      */
195     public synchronized int getMaximumSize() {
196         return maximumSize;
197     }
198 
199     /**
200      * Set the int maximumSize.
201      * @param maximumSize int
202      */
203     public synchronized void setMaximumSize(int maximumSize) {
204         if (maximumSize > Integer.MAX_VALUE || maximumSize < getMinimumSize()) {
205             throw new IllegalArgumentException(Integer.toString(maximumSize));
206         }
207         this.maximumSize = maximumSize;
208     }
209 
210     /**
211      * Get the int minimumSize.
212      * @return int
213      */
214     public synchronized int getMinimumSize() {
215         return minimumSize;
216     }
217 
218     /**
219      * Set the int minimumSize.
220      * @param minimumSize int
221      */
222     public synchronized void setMinimumSize(int minimumSize) {
223         if (minimumSize < 0 || minimumSize > getMaximumSize()) {
224             throw new IllegalArgumentException(Integer.toString(minimumSize));
225         }
226         this.minimumSize = minimumSize;
227     }
228 
229     /**
230      * Get the boolean resizable.
231      * @return boolean
232      */
233     public boolean isResizable() {
234         return resizable;
235     }
236 
237     /**
238      * Set the boolean resizable.
239      * @param resizable boolean
240      */
241     public void setResizable(boolean resizable) {
242         this.resizable = resizable;
243     }
244 
245 }