KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > generation > mivisitor > ReverseFieldAdder


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but 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 library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.speedo.generation.mivisitor;
19
20 import org.objectweb.speedo.metadata.SpeedoField;
21 import org.objectweb.speedo.metadata.SpeedoExtension;
22 import org.objectweb.speedo.metadata.SpeedoClass;
23 import org.objectweb.speedo.metadata.SpeedoCollection;
24 import org.objectweb.speedo.metadata.SpeedoMap;
25 import org.objectweb.speedo.metadata.SpeedoArray;
26 import org.objectweb.speedo.api.SpeedoProperties;
27 import org.objectweb.speedo.api.SpeedoException;
28 import org.objectweb.speedo.generation.enhancer.Util;
29 import org.objectweb.util.monolog.api.BasicLevel;
30 import org.objectweb.asm.Type;
31
32 /**
33  * Add the reverse extensions on the forgetten side. In addition the mapping
34  * is added too.
35  *
36  * @author S.Chassande-Barrioz
37  */

38 public class ReverseFieldAdder extends AbstractMetaInfoVisitor {
39
40     public ReverseFieldAdder() {
41     }
42
43     public ReverseFieldAdder(MetaInfoVisitor mim) {
44         super(mim);
45     }
46
47     protected String JavaDoc getLoggerName() {
48         return LOGGER_NAME + ".reverseField";
49     }
50
51     public void visitExtension(SpeedoExtension se) throws SpeedoException {
52         debug = logger.isLoggable(BasicLevel.DEBUG);
53         if (!SpeedoProperties.VENDOR_NAME.equals(se.vendorName)
54                 || !SpeedoProperties.REVERSE_FIELD.equals(se.key)) {
55             super.visitExtension(se);
56             return;
57         }
58
59         //check that the extension REVERSE_FIELD is specified for a SpeedoField
60
if (!(se.jdoElement instanceof SpeedoField)) {
61             SpeedoClass sc = getSpeedoClass(se.jdoElement);
62             logger.log(BasicLevel.ERROR, "You have specified the reverse field ('"
63                     + se.value + "') in other thing than a field tag ('"
64                     + se.jdoElement.toString() + "')" +
65                     (sc == null
66                     ? ""
67                     : " in class '" + sc.getFQName() + "' of the descriptor '"
68                     + sc.jdoPackage.jdoXMLDescriptor.xmlFile));
69             super.visitExtension(se);
70             return;
71         }
72
73         SpeedoField sf = (SpeedoField) se.jdoElement;
74         SpeedoField reverse = getReverseField(sf,se.value);
75         if (reverse == null) {
76             throwError("No reverse field '" + se.value + "' found for the", sf);
77             super.visitExtension(se);
78             return;
79         }
80         SpeedoExtension _se = reverse.getExtension(
81                 SpeedoProperties.VENDOR_NAME, SpeedoProperties.REVERSE_FIELD);
82         if (_se == null) {
83             //define the extension REVERSE_FIELD on the reverse field
84
_se = new SpeedoExtension(SpeedoProperties.VENDOR_NAME,
85                     SpeedoProperties.REVERSE_FIELD,
86                     sf.name, reverse);
87             logger.log(BasicLevel.DEBUG, "add the extension("
88                     + SpeedoProperties.REVERSE_FIELD + ", " + sf.name
89                     +") on the field '" + reverse.name + "'");
90             reverse.addExtension(_se);
91         }
92
93         // compute relationType
94
if (sf.jdoTuple != null) {
95             if (reverse.jdoTuple != null) {
96                 sf.relationType = SpeedoField.MANY_MANY_RELATION;
97                 reverse.relationType = SpeedoField.MANY_MANY_RELATION;
98             } else {
99                 sf.relationType = SpeedoField.ONE_MANY_RELATION;
100                 reverse.relationType = SpeedoField.MANY_ONE_RELATION;
101             }
102         } else {
103             if (reverse.jdoTuple != null) {
104                 sf.relationType = SpeedoField.MANY_ONE_RELATION;
105                 reverse.relationType = SpeedoField.ONE_MANY_RELATION;
106             } else {
107                 sf.relationType = SpeedoField.ONE_ONE_RELATION;
108                 reverse.relationType = SpeedoField.ONE_ONE_RELATION;
109             }
110         }
111
112         checkExtension(sf, se, reverse,
113                 SpeedoProperties.TARGET_FK, SpeedoProperties.SOURCE_FK);
114         checkExtension(sf, se, reverse,
115                 SpeedoProperties.SOURCE_FK, SpeedoProperties.TARGET_FK);
116         checkExtension(sf, se, reverse,
117                 SpeedoProperties.JOIN_TABLE, SpeedoProperties.JOIN_TABLE);
118         super.visitExtension(se);
119     }
120
121     /**
122      * Check if a SpeedoField has a specified SpeedoExtension ('ext1'). If yes
123      * the extension 'ext2' is add on the reverse field with the same value.
124      * If the meta data is malformed then the visit continue to the next
125      * MetaDatavisitor.
126      * @param sf is the SpeedoField containing the SpeedoExtension 'ext1'
127      * @param se the parameter to the visitor
128      * @param reverse the SpeedoField which must contains at the end the options
129      * ext2 if the extension ext1 is defined on the field 'sf'
130      * @param ext1 a name of a SpeedoExtension (@see SpeedoProperties)
131      * @param ext2 a name of a SpeedoExtension (@see SpeedoProperties)
132      */

133     private SpeedoExtension checkExtension(SpeedoField sf,
134                                 SpeedoExtension se,
135                                 SpeedoField reverse,
136                                 String JavaDoc ext1,
137                                 String JavaDoc ext2) throws SpeedoException {
138         SpeedoExtension _se = sf.getExtension(SpeedoProperties.VENDOR_NAME, ext1);
139         if (_se != null) {
140             SpeedoExtension __se = reverse.getExtension(SpeedoProperties.VENDOR_NAME, ext2);
141             if (__se == null) {
142                 //define the extension SOURCE_FK on the reverse field
143
__se = new SpeedoExtension(SpeedoProperties.VENDOR_NAME, ext2, _se.value, reverse);
144                 logger.log(BasicLevel.DEBUG, "add the extension(" + ext2
145                         + ", " + _se.value +") on the field '"
146                         + reverse.name + "'");
147                 reverse.addExtension(__se);
148             } else if (!__se.value.equals(_se.value)) {
149                 throwError("A bad mapping has been specified on the reverse field '"
150                         + se.value + "' for the ", sf);
151                 super.visitExtension(se);
152                 return _se;
153             } else if (debug) {
154                 SpeedoClass sc1 = getSpeedoClass(sf);
155                 SpeedoClass sc2 = getSpeedoClass(reverse);
156                 logger.log(BasicLevel.DEBUG, "You could remove one of the following extensions:"
157                         + "\n- .jdo: '" + sc1.jdoPackage.jdoXMLDescriptor.xmlFile
158                         + "', class: '" + sc1.getFQName()
159                         + "', field: '" + sf.name
160                         + "', extension: '" + ext1 + "'"
161
162                         + "\n- .jdo: '" + sc2.jdoPackage.jdoXMLDescriptor.xmlFile
163                         + "', class: '" + sc2.getFQName()
164                         + "', field: '" + reverse.name
165                         + "', extension: '" + ext2 + "'"
166                         );
167             }
168         }
169         return _se;
170     }
171
172     /**
173      * Retrieves the SpeedoField instance which is the reverse of a given
174      * SpeedoField. The name of reverse field is specified by 'rfn'.
175      * @param sf is the SpeedoField which the reverse SpeedoField must be retrieved
176      * @param rfn the name of the reverse field
177      */

178     public static SpeedoField getReverseField(SpeedoField sf, String JavaDoc rfn) throws SpeedoException {
179         String JavaDoc className = null;
180         if (sf.jdoTuple != null) {
181             if (sf.jdoTuple instanceof SpeedoCollection) {
182                 className = (String JavaDoc) ((SpeedoCollection) sf.jdoTuple).elementType;
183             } else if (sf.jdoTuple instanceof SpeedoMap) {
184                 className = (String JavaDoc) ((SpeedoMap) sf.jdoTuple).valueType;
185             } else if (sf.jdoTuple instanceof SpeedoArray) {
186                 className = Util.type(Type.getType(sf.desc));
187             }
188         } else {
189             className = Util.type(Type.getType(sf.desc));
190         }
191         SpeedoClass sc = sf.jdoClass.jdoPackage
192                 .jdoXMLDescriptor.getSpeedoClass(className, true);
193         if (sc == null) {
194             sc = sf.jdoClass.jdoPackage.jdoXMLDescriptor.getSpeedoClass(
195                     getSpeedoClass(sf).jdoPackage.name + "." + className, true);
196         }
197         if (sc == null) {
198             throwError("No persistent class '" + className + "' found for managing the ", sf);
199             return null;
200         }
201         return (SpeedoField) sc.jdoField.get(rfn);
202     }
203
204     /**
205      * Log a pretty error message with the context (field, class, xml desc)
206      * @param msg the additionnal message
207      * @param sf the field which is managed
208      */

209     public static void throwError(String JavaDoc msg, SpeedoField sf) throws SpeedoException {
210         throw new SpeedoException(msg + " field '" + sf.name
211                 + "' of the class '" + sf.jdoClass.getFQName()
212                 + "' in the descriptor '"
213                 + sf.jdoClass.jdoPackage.jdoXMLDescriptor.xmlFile + "'");
214     }
215
216
217 }
218
Popular Tags