KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jorm > generator > lib > FPNCGenerator


1 /**
2  * Copyright (C) 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.jorm.generator.lib;
19
20 import org.apache.velocity.VelocityContext;
21 import org.apache.velocity.context.Context;
22 import org.objectweb.jorm.api.PException;
23 import org.objectweb.jorm.compiler.api.JormCompilerParameter;
24 import org.objectweb.jorm.compiler.api.PExceptionCompiler;
25 import org.objectweb.jorm.metainfo.api.Class;
26 import org.objectweb.jorm.metainfo.api.NameDef;
27 import org.objectweb.jorm.metainfo.api.Package;
28 import org.objectweb.jorm.metainfo.api.PrimitiveElement;
29 import org.objectweb.jorm.metainfo.api.TypedElement;
30 import org.objectweb.jorm.type.api.PType;
31 import org.objectweb.jorm.util.io.api.TargetHolder;
32 import org.objectweb.medor.expression.api.Expression;
33 import org.objectweb.medor.expression.api.ExpressionException;
34 import org.objectweb.medor.expression.api.Operand;
35 import org.objectweb.medor.expression.api.Operator;
36 import org.objectweb.medor.expression.api.ParameterOperand;
37 import org.objectweb.medor.expression.lib.Equal;
38 import org.objectweb.medor.expression.lib.NotEqual;
39 import org.objectweb.util.monolog.api.BasicLevel;
40 import org.objectweb.util.monolog.api.Logger;
41
42 import java.io.File JavaDoc;
43 import java.io.FileWriter JavaDoc;
44 import java.util.Collection JavaDoc;
45 import java.util.HashMap JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.Map JavaDoc;
48
49 /**
50  *
51  * @author S.Chassande-Barrioz
52  */

53 public class FPNCGenerator extends CommonGenerator {
54
55     public CommonHelper helper;
56
57
58
59     public void generate(Class JavaDoc clazz,
60                          TargetHolder holder,
61                          JormCompilerParameter cp) throws PException {
62
63         Collection JavaDoc nds = clazz.getNameDefs();
64         Class JavaDoc classWithNd = clazz;
65         while(nds.size() < 1 && classWithNd.getInheritedClassNumber() > 0) {
66             classWithNd = (Class JavaDoc) classWithNd.getSuperClasses().iterator().next();
67             nds = classWithNd.getNameDefs();
68         }
69         if (nds.size() < 1) {
70             logger.log(BasicLevel.WARN, "FPNC: No NameDef defined for the class " + clazz.getFQName());
71             return;
72         }
73         if (nds.size() == 1) {
74             generate(clazz, (NameDef) nds.iterator().next(), null, holder);
75         } else {
76             Iterator JavaDoc it = nds.iterator();
77             while(it.hasNext()) {
78                 NameDef nd = (NameDef) it.next();
79                 String JavaDoc ndName = (nd.getName() != null
80                     && nd.getName().length() == 0
81                     ? null
82                     : nd.getName());
83                 generate(clazz, nd, ndName, holder);
84             }
85         }
86     }
87
88     /**
89      * This method generates a XFPNC file corresponding to the clazz
90      * parameter in the directory parameter.
91      * @param clazz The clazz requiring the generation of a PNamingContext.
92      * @param nd The NameDef to use
93      * @param ndName The name def name to use fot the package name
94      * (can be null)
95      * @param holder The target holder which allows to create files.
96      */

97     private void generate(Class JavaDoc clazz,
98                           NameDef nd,
99                           String JavaDoc ndName,
100                           TargetHolder holder) throws PException {
101         Expression exp;
102         try {
103             exp = clazz.getInheritanceFilter(nd);
104         } catch (ExpressionException e) {
105             throw new PException(e);
106         }
107         if (exp == null) {
108             return;
109         }
110         PType expType = exp.getType();
111         if (expType.getTypeCode() != PType.TYPECODE_BOOLEAN
112             && expType.getTypeCode() != PType.TYPECODE_OBJBOOLEAN) {
113             return;
114         }
115         
116
117         // Calculate fileName
118
String JavaDoc packName = ((Package JavaDoc) clazz.getParent()).getName();
119         if (ndName != null) {
120             if (packName != null && packName.length() > 0) {
121                 packName += "." + ndName;
122             } else {
123                 packName = ndName;
124             }
125         }
126         String JavaDoc className = clazz.getName() + "FPNC";
127         String JavaDoc fileName = className;
128         if (packName != null && packName.length() > 0) {
129             fileName = packName + "." + fileName;
130             fileName = fileName.replace('.', File.separatorChar);
131         }
132         logger.log(BasicLevel.DEBUG, "Generate the " + fileName);
133
134
135         Context ctx = new VelocityContext();
136         ctx.put("class", clazz);
137         ctx.put("helper", this);
138         ctx.put("header", GEN_TEMPLATE_DIR + "Header.vm");
139         ctx.put("className", className);
140         ctx.put("packName", packName);
141         boolean isComposite = false;
142         if (nd.isNameRef()) {
143             isComposite = true;
144             ctx.put("isComposite", Boolean.TRUE);
145             ctx.put("codingType", "PNameCoder.CTCOMPOSITE");
146             ctx.put("compositeName", nd.getNameRef().getCompositeName());
147         } else if (nd.isFieldName()) {
148             isComposite = false;
149             ctx.put("isComposite", Boolean.FALSE);
150             TypedElement te = clazz.getTypedElement(nd.getFieldName());
151             if (te == null) {
152                 throw new PException("The field '" + nd.getFieldName()
153                     + "' used in the namedef of the class '"
154                     + clazz.getFQName() + "' is not defined.");
155             } else if (!(te instanceof PrimitiveElement)) {
156                 throw new PException("MalFormed Meta information: the field '"
157                     + nd.getFieldName() + "' used in the namedef of the class '"
158                     + clazz.getFQName() + "' is not a primitive element.");
159             }
160             ctx.put("codingType", getCTDeclaration(te.getType()));
161         }
162
163         FPNCMatchInfo mi;
164         try {
165             mi = new FPNCMatchInfo(exp, isComposite, logger);
166         } catch (ExpressionException e) {
167             throw new PException(e, "Generation of " + fileName);
168         }
169         if (mi.filter.length() == 0) {
170             mi.filter.append("true");
171         }
172         ctx.put("mi", mi);
173
174         //Generate the file
175
try {
176             FileWriter JavaDoc fw = holder.getFileWriter(fileName + ".java");
177             if (template == null) {
178                 template = velocityEngine.getTemplate(GEN_TEMPLATE_DIR + "FPNC.vm");
179             }
180             template.merge(ctx, fw);
181             fw.flush();
182             fw.close();
183         } catch (Exception JavaDoc e) {
184             throw new PExceptionCompiler(e, "Problem while generating " + fileName + ".java");
185         }
186     }
187
188     public class FPNCMatchInfo extends NamingFilterExpressionHelper {
189
190         /**
191          * Indicates if the naming is based on a composite name.
192          */

193         public boolean isComposite;
194
195         /**
196          * When the naming is based on a single field (not a composite). This field
197          * is the type of the naming field.
198          */

199         public PType singleFieldPType = null;
200
201         /**
202          * When the naming is based on a single field (not a composite). This field
203          * is the name of the naming field. By default this field is equals to 'o'.
204          * this field is used as parameter name in match methods.
205          */

206         public String JavaDoc singleFieldName = "o";
207
208         /**
209          * Builds a FPNCMatchInfo fro an expression.
210          * @param e is the filter expression
211          * @param isComposite indicates if the naming is composite or not. If yes a
212          * composite name will be used to reach naming field.
213          */

214         public FPNCMatchInfo(Expression e,
215                              boolean isComposite,
216                              Logger logger)
217             throws PException, ExpressionException {
218             super(logger);
219             this.isComposite = isComposite;
220             fillMatchInfo(e);
221         }
222
223         public PType getSingleFieldPType() {
224             return singleFieldPType;
225         }
226
227         public String JavaDoc getSingleFieldName() {
228             return singleFieldName;
229         }
230
231         public String JavaDoc toString() {
232             return super.toString()
233                 + " / singleFieldName=" + singleFieldName
234                 + " / singleFieldPType=" + singleFieldPType
235                 ;
236         }
237
238         protected void fillMatchInfo(ParameterOperand po) throws PException, ExpressionException {
239             logger.log(BasicLevel.DEBUG, "ParameterOperand " + po.getName());
240             if (isComposite) {
241                 if (field2declarations.get(po.getName()) == null) {
242                     if (field2declarations.size() == 0) {
243                         field2declarations.put("", "PNameGetter png = (PNameGetter) o;");
244                     }
245                     StringBuffer JavaDoc declaration = new StringBuffer JavaDoc();
246                     declaration.append(po.getType().getJavaName());
247                     declaration.append(' ');
248                     declaration.append(po.getName());
249                     declaration.append(" = png.pnGet");
250                     declaration.append(getCoderName(po.getType()));
251                     declaration.append("Field(\"");
252                     declaration.append(po.getName());
253                     declaration.append("\");");
254                     field2declarations.put(po.getName(), declaration);
255                     if (logger.isLoggable(BasicLevel.DEBUG)) {
256                         logger.log(BasicLevel.DEBUG, "Add declaration: " + declaration);
257                     }
258                 }
259                 filter.append(po.getName());
260             } else {
261                 if (singleFieldPType != null && singleFieldPType != po.getType()) {
262                     throw new ExpressionException("Several parameters with a non composite name");
263                 }
264                 singleFieldPType = po.getType();
265                 singleFieldName = po.getName();
266                 filter.append(singleFieldName);
267                 logger.log(BasicLevel.DEBUG, "singleFieldPType " + singleFieldPType);
268                 logger.log(BasicLevel.DEBUG, "singleFieldName " + singleFieldName);
269             }
270         }
271     }
272 }
273
Popular Tags