001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.vfny.geoserver.global.dto;
006:
007: import com.vividsolutions.jts.geom.Envelope;
008: import java.lang.reflect.Constructor;
009: import java.util.Iterator;
010: import java.util.List;
011: import java.util.Map;
012:
013: /**
014: * CloneLibrary purpose is used to try and Set up a Deep Copy for DTO objets.
015: *
016: * <p>
017: * Static Library class for cloning complex structures independant of their
018: * contents.
019: * </p>
020: *
021: * <p>
022: * Jody here - this is much more accessable when presented to the user as new
023: * Type( Type ) idiom. Java clone is messed up, I have seen several projects
024: * move to a copy() method or the above idom.
025: * </p>
026: *
027: * <p>
028: * For the here and now we can use the above Idom. This will even work with all
029: * of our lists and Maps since we are only ever using Strings (imutable) in
030: * them.
031: * </p>
032: *
033: * @author dzwiers, Refractions Research, Inc.
034: * @version $Id: CloneLibrary.java 7682 2007-10-30 16:32:01Z aaime $
035: */
036: public final class CloneLibrary {
037: /**
038: * clone purpose.
039: *
040: * <p>
041: * Clones a List so that it matches the requirements that the returned
042: * object would be equal to the source.
043: * </p>
044: *
045: * @param source The list to be cloned.
046: *
047: * @return An exact clone of the list.
048: *
049: * @throws CloneNotSupportedException
050: *
051: * @see java.lang.Object#clone()
052: * @see java.util.List
053: */
054: public static List clone(List source)
055: throws CloneNotSupportedException {
056: if (source == null) {
057: return null;
058: }
059:
060: List result;
061:
062: //to get an exact instance, need to match sub-types for .equals method
063: try {
064: Class c = source.getClass();
065: Constructor ct = c.getConstructor(new Class[0]);
066: result = (List) ct.newInstance(new Object[0]);
067: } catch (Exception e) {
068: throw new CloneNotSupportedException();
069: }
070:
071: Object[] lst = source.toArray();
072:
073: for (int i = 0; i < lst.length; i++) {
074: result.add(i, clone(lst[i]));
075: }
076:
077: return result;
078: }
079:
080: /**
081: * clone purpose.
082: *
083: * <p>
084: * Clones a Map so that it matches the requirements that the returned
085: * object would be equal to the source.
086: * </p>
087: *
088: * @param source The Map to be cloned.
089: *
090: * @return An exact clone of the list.
091: *
092: * @throws CloneNotSupportedException
093: *
094: * @see java.lang.Object#clone()
095: * @see java.util.Map
096: */
097: public static Map clone(Map source)
098: throws CloneNotSupportedException {
099: if (source == null) {
100: return null;
101: }
102:
103: Map result;
104:
105: //to get an exact instance, need to match sub-types for .equals method
106: try {
107: Class c = source.getClass();
108: Constructor ct = c.getConstructor(new Class[0]);
109: result = (Map) ct.newInstance(new Object[0]);
110: } catch (Exception e) {
111: throw new CloneNotSupportedException();
112: }
113:
114: //result.putAll(source);
115: Iterator keyIter = source.keySet().iterator();
116:
117: while (keyIter.hasNext()) {
118: Object key = keyIter.next();
119: result.put(key, clone(source.get(key)));
120: }
121:
122: return result;
123: }
124:
125: /**
126: * clone purpose.
127: *
128: * <p>
129: * Clones a Envelope so that it matches the requirements that the returned
130: * object would be equal to the source.
131: * </p>
132: *
133: * @param e The Envelope to be cloned.
134: *
135: * @return An exact clone of the list.
136: *
137: * @see java.lang.Object#clone()
138: * @see com.vividsolutions.jts.geom.Envelope
139: */
140: public static Envelope clone(Envelope e) {
141: if (e == null)
142: return null;
143: Envelope result = new Envelope(e);
144:
145: return result;
146: }
147:
148: /**
149: * clone purpose.
150: *
151: * <p>
152: * used to check class type and clone it.
153: * </p>
154: *
155: * @param ds the DataStructure to clone.
156: *
157: * @return a clone of the parameter
158: */
159: private static Object clone(DataTransferObject ds) {
160: return ds.clone();
161: }
162:
163: /**
164: * Clone a string array
165: *
166: * @param array DOCUMENT ME!
167: *
168: * @return DOCUMENT ME!
169: */
170: public static String[] clone(String[] array) {
171: String[] copy = new String[array.length];
172: System.arraycopy(array, 0, copy, 0, array.length);
173:
174: return copy;
175: }
176:
177: /**
178: * clone purpose.
179: *
180: * <p>
181: * to make the compiler happy, should never be here.
182: * </p>
183: *
184: * @param obj the parameter to return, does nothing.
185: *
186: * @return returns the parameter
187: */
188: private static Object clone(Object obj) {
189: return obj;
190: }
191: }
|