001: /*
002: * This file is part of JGAP.
003: *
004: * JGAP offers a dual license model containing the LGPL as well as the MPL.
005: *
006: * For licensing information please see the file license.txt included with JGAP
007: * or have a look at the top of class org.jgap.Chromosome which representatively
008: * includes the JGAP license policy applicable for any file delivered with JGAP.
009: */
010: package org.jgap.impl;
011:
012: import java.io.*;
013: import java.util.*;
014: import org.jgap.*;
015: import org.jgap.util.*;
016:
017: /**
018: * Ordered chain of NaturalSelectors. With this container you can plugin
019: * NaturalSelector implementations which will be performed either before (pre-)
020: * or after (post-selectors) registered genetic operations have been applied.
021: *
022: * @see Configuration
023: * @see Genotype
024: *
025: * @author Klaus Meffert
026: * @since 1.1
027: */
028: public class ChainOfSelectors implements Serializable, ICloneable,
029: Comparable {
030: /** String containing the CVS revision. Read out via reflection!*/
031: private final static String CVS_REVISION = "$Revision: 1.19 $";
032:
033: /**
034: * Ordered list holding the NaturalSelector's.
035: * Intentionally used as a decorator and not via inheritance!
036: */
037: private List m_selectors;
038:
039: private Configuration m_conf;
040:
041: /**
042: * Only for dynamic instantiation.
043: *
044: * @author Klaus Meffert
045: * @since 3.2
046: */
047: public ChainOfSelectors() {
048: this (Genotype.getStaticConfiguration());
049: }
050:
051: public ChainOfSelectors(Configuration a_conf) {
052: m_selectors = new Vector();
053: m_conf = a_conf;
054: }
055:
056: /**
057: * Adds a natural selector to the chain.
058: *
059: * @param a_selector the selector to be added
060: * @throws InvalidConfigurationException
061: *
062: * @author Klaus Meffert
063: * @since 1.1 (previously part of class Configuration)
064: */
065: public void addNaturalSelector(NaturalSelector a_selector)
066: throws InvalidConfigurationException {
067: if (a_selector == null) {
068: throw new InvalidConfigurationException(
069: "This Configuration object is locked. Settings may not be "
070: + "altered.");
071: }
072: m_selectors.add(a_selector);
073: }
074:
075: /**
076: *
077: * @param a_c Collection to add all elements from
078: * @throws InvalidConfigurationException
079: *
080: * @author Klaus Meffert
081: * @since 1.1
082: */
083: public void addAll(Collection a_c)
084: throws InvalidConfigurationException {
085: Iterator it = a_c.iterator();
086: while (it.hasNext()) {
087: NaturalSelector selector = (NaturalSelector) it.next();
088: addNaturalSelector(selector);
089: }
090: }
091:
092: /**
093: * @return number of selectors in list
094: *
095: * @author Klaus Meffert
096: * @since 1.1 (previously part of class Configuration)
097: */
098: public int size() {
099: return m_selectors.size();
100: }
101:
102: /**
103: * @return true if number of selectors is zero
104: *
105: * @author Klaus Meffert
106: * @since 1.1
107: */
108: public boolean isEmpty() {
109: return size() == 0;
110: }
111:
112: public int hashCode() {
113: return m_selectors.hashCode();
114: }
115:
116: /**
117: *
118: * @param a_obj Object
119: * @return boolean
120: *
121: * @author Klaus Meffert
122: * @since 1.1
123: */
124: public boolean equals(final Object a_obj) {
125: try {
126: ChainOfSelectors c2 = (ChainOfSelectors) a_obj;
127: if (c2 == null) {
128: return false;
129: }
130: return m_selectors.equals(c2.m_selectors);
131: } catch (ClassCastException cex) {
132: return false;
133: }
134: }
135:
136: /**
137: * Returns a Selector with specific index in the list.
138: *
139: * @param a_index the index of the Selector to read from the list
140: * @return NaturalSelector
141: *
142: * @author Klaus Meffert
143: * @since 1.1
144: */
145: public NaturalSelector get(final int a_index) {
146: return (NaturalSelector) m_selectors.get(a_index);
147: }
148:
149: /**
150: * Clears all registered selectors.
151: *
152: * @author Klaus Meffert
153: * @since 1.1
154: *
155: */
156: public void clear() {
157: m_selectors.clear();
158: }
159:
160: /**
161: * @return Iterator for iterating over list of selectors
162: *
163: * @author Klaus Meffert
164: * @since 1.1
165: */
166: public Iterator iterator() {
167: return m_selectors.iterator();
168: }
169:
170: /**
171: * @return deep clone of this instance
172: *
173: * @author Klaus Meffert
174: * @since 3.2
175: */
176: public Object clone() {
177: try {
178: ChainOfSelectors result = new ChainOfSelectors(m_conf);
179: List v = new Vector();
180: for (int i = 0; i < m_selectors.size(); i++) {
181: INaturalSelector o = (INaturalSelector) m_selectors
182: .get(i);
183: Object clone;
184: ICloneHandler handler = m_conf.getJGAPFactory()
185: .getCloneHandlerFor(o, null);
186: if (handler != null) {
187: clone = handler.perform(o, null, null);
188: } else {
189: throw new IllegalStateException(
190: "No clone handler found for class "
191: + o.getClass().getName());
192: }
193: v.add(clone);
194: }
195: result.m_selectors = v;
196: return result;
197: } catch (Throwable t) {
198: throw new CloneException(t);
199: }
200: }
201:
202: /**
203: * The compareTo-method. Here we simply compare the class names of the
204: * contained selectors as INaturalSelector does not contain interface
205: * Comparable.
206: *
207: * @param a_other the other object to compare
208: * @return -1, 0, 1
209: *
210: * @author Klaus Meffert
211: * @since 3.2
212: */
213: public int compareTo(Object a_other) {
214: if (a_other == null) {
215: return 1;
216: } else {
217: ChainOfSelectors other = (ChainOfSelectors) a_other;
218: int size = m_selectors.size();
219: if (other.m_selectors.size() < size) {
220: return 1;
221: }
222: if (other.m_selectors.size() > m_selectors.size()) {
223: return -1;
224: }
225: for (int i = 0; i < size; i++) {
226: // Normally we would do the following:
227: // INaturalSelector selector = (INaturalSelector)m_selectors.get(i);
228: // INaturalSelector selectorOther = (INaturalSelector)other.m_selectors.get(i);
229: // int result = selector.compareTo(selectorOther);
230:
231: // But INaturalSelector does not support Cmparable, so:
232: String name = m_selectors.get(i).getClass().getName();
233: String nameOther = other.m_selectors.get(i).getClass()
234: .getName();
235: int result = name.compareTo(nameOther);
236: if (result != 0) {
237: return result;
238: }
239: }
240: }
241: return 0;
242: }
243: }
|