KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > Utils


1 /*
2   Copyright (C) 2003 Laurent Martelli <laurent@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public
15   License along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA */

18
19 package org.objectweb.jac.core;
20
21 import java.lang.reflect.Modifier JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import org.apache.log4j.Logger;
25 import org.objectweb.jac.core.rtti.ClassItem;
26 import org.objectweb.jac.core.rtti.ClassRepository;
27 import org.objectweb.jac.core.rtti.CollectionItem;
28 import org.objectweb.jac.core.rtti.FieldItem;
29 import org.objectweb.jac.core.rtti.MethodItem;
30 import org.objectweb.jac.core.rtti.NoSuchMethodException;
31 import org.objectweb.jac.core.rtti.RttiAC;
32 import org.objectweb.jac.util.ExtArrays;
33
34 public class Utils {
35     static Logger logger = Logger.getLogger("clone");
36
37     /**
38      * "Semantic" clone. Same as <code>clone(o,null)</code>
39      *
40      * @param o the object to clone
41      * @return the cloned object
42      *
43      * @see #clone(Object,FieldItem)
44      */

45     public static Object JavaDoc clone(Object JavaDoc o)
46         throws InstantiationException JavaDoc, IllegalAccessException JavaDoc, Exception JavaDoc
47     {
48         return clone(o,(FieldItem)null);
49     }
50
51     /**
52      * "Semantic" clone. Collections marked as aggregation are
53      * recursively cloned (objects in the collection are cloned),
54      * otherwise the collection of the cloned objet will contains the
55      * same objects as the source object.
56      *
57      * @param o the object to clone
58      * @param ignoredRelation do not clone this relation and leave it
59      * empty. If null, all relations are cloned.
60      * @return the cloned object
61      *
62      * @see #clone(Object)
63      */

64     public static Object JavaDoc clone(Object JavaDoc o, FieldItem ignoredRelation)
65         throws InstantiationException JavaDoc, IllegalAccessException JavaDoc, Exception JavaDoc
66     {
67         logger.debug("Cloning "+o);
68         ClassRepository cr = ClassRepository.get();
69         ClassItem cli = cr.getClass(o);
70         Object JavaDoc clone = cli.newInstance();
71         Iterator JavaDoc i = cli.getAllFields().iterator();
72         while (i.hasNext()) {
73             FieldItem field = (FieldItem)i.next();
74             if (field.isCalculated() || ignoredRelation==field)
75                 continue;
76             if (field.isPrimitive()) {
77                 logger.debug(" copying value of fied "+field.getName());
78                 try {
79                     Object JavaDoc fieldValue = field.getThroughAccessor(o);
80                     
81                     // Cloneable is useless in this generic context
82
try {
83                         MethodItem mClone = cr.getClass(fieldValue).getMethod("clone()");
84                         if (mClone!=null && Modifier.isPublic(mClone.getModifiers()))
85                             fieldValue = mClone.invoke(fieldValue, ExtArrays.emptyObjectArray);
86                     } catch(NoSuchMethodException JavaDoc e) {
87                     }
88                     field.setThroughWriter(clone,fieldValue);
89                 } catch (Exception JavaDoc e) {
90                     logger.error("clone("+o+"): failed to clone field "+field,e);
91                 }
92             } else if (field instanceof CollectionItem) {
93                 CollectionItem collection = (CollectionItem)field;
94                 logger.debug(" copying collection "+field.getName());
95                 if (collection.isMap()) {
96                 } else {
97                     Iterator JavaDoc j = ((Collection JavaDoc)collection.getThroughAccessor(o)).iterator();
98                     while(j.hasNext()) {
99                         Object JavaDoc item = j.next();
100                         if (collection.isAggregation()) {
101                             item = clone(item,(FieldItem)field.getAttribute(RttiAC.OPPOSITE_ROLE));
102                         }
103                         collection.addThroughAdder(clone,item);
104                     }
105                 }
106             } else {
107                 field.setThroughWriter(clone,field.getThroughAccessor(o));
108             }
109         }
110         logger.debug(o+" cloned");
111         return clone;
112     }
113
114     public static Object JavaDoc clone(Object JavaDoc o, String JavaDoc ignoredRelation)
115         throws InstantiationException JavaDoc, IllegalAccessException JavaDoc, Exception JavaDoc
116     {
117         return clone(o,ClassRepository.get().getClass(o).getField(ignoredRelation));
118     }
119 }
120
Popular Tags