KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > layoutsupport > BeanCodeManager


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.form.layoutsupport;
21
22 import java.util.Iterator JavaDoc;
23 import java.lang.reflect.*;
24
25 import org.netbeans.modules.form.*;
26 import org.netbeans.modules.form.codestructure.*;
27
28 /**
29  * Experimental class which manages code structure for a bean with a set of
30  * properties. It creates code expression for the bean and manages its
31  * initialization code for constructor and properties, updating the code on
32  * properties changes.
33  *
34  * @author Tomas Pavek
35  */

36
37 final class BeanCodeManager
38 {
39     private Class JavaDoc beanClass;
40     private FormProperty[] properties; // supposing bean has a constant set of properties
41
private CodeExpression[] propertyExpressions;
42
43     private int creationStyle;
44     private boolean forceEmptyConstructor;
45
46     private CreationDescriptor creationDesc;
47     private CreationDescriptor.Creator currentCreator;
48
49     private CodeStructure codeStructure;
50
51     private CodeExpression beanExpression;
52     private CodeGroup beanCode;
53
54     private boolean isVariableSet;
55     private int variableType;
56
57     private boolean readingDone;
58
59     // constructor for a new expression
60
public BeanCodeManager(Class JavaDoc beanClass,
61                            FormProperty[] beanProperties,
62                            int creationStyle,
63                            boolean forceEmptyCtor,
64                            CodeStructure codeStructure,
65                            int defaultVariableType,
66                            CodeGroup beanCode)
67     {
68         this.beanClass = beanClass;
69         this.properties = beanProperties;
70         this.creationStyle = creationStyle | CreationDescriptor.CHANGED_ONLY;
71         this.forceEmptyConstructor = forceEmptyCtor;
72         this.codeStructure = codeStructure;
73         this.variableType = defaultVariableType;
74         this.beanCode = beanCode;
75
76         isVariableSet = false;
77
78         creationDesc = CreationFactory.getDescriptor(beanClass);
79
80         beanExpression = codeStructure.createDefaultExpression();
81
82         readingDone = true;
83         updateCode();
84     }
85
86     // constructor for reading the expression from code
87
public BeanCodeManager(Class JavaDoc beanClass,
88                            FormProperty[] beanProperties,
89                            int creationStyle,
90                            boolean forceEmptyCtor,
91                            boolean allowChangesFiring,
92                            CodeExpression beanExpression,
93                            CodeGroup beanCode)
94     {
95         this.beanClass = beanClass;
96         this.properties = beanProperties;
97         this.creationStyle = creationStyle | CreationDescriptor.CHANGED_ONLY;
98         this.forceEmptyConstructor = forceEmptyCtor;
99         this.beanExpression = beanExpression;
100         this.codeStructure = beanExpression.getCodeStructure();
101         this.beanCode = beanCode;
102
103         readingDone = false;
104
105         CodeVariable var = beanExpression.getVariable();
106         CodeStatement variableStatement = var != null ?
107                                       var.getAssignment(beanExpression) : null;
108
109         isVariableSet = variableStatement != null;
110         variableType = var != null ? var.getType() : CodeVariable.LOCAL;
111
112         // find creation descriptor
113
creationDesc = CreationFactory.getDescriptor(beanClass);
114         if (creationDesc != null) {
115             // find creator, read creation code
116
CodeExpression creationExpressions[] =
117                 beanExpression.getOrigin().getCreationParameters();
118             Class JavaDoc[] paramTypes = new Class JavaDoc[creationExpressions.length];
119             for (int i=0; i < creationExpressions.length; i++)
120                 paramTypes[i] = creationExpressions[i].getOrigin().getType();
121
122             currentCreator = CreationFactory.findCreator(creationDesc, paramTypes);
123
124             if (currentCreator != null) {
125                 String JavaDoc[] creatorPropNames = currentCreator.getPropertyNames();
126                 for (int i=0; i < creatorPropNames.length; i++) {
127                     String JavaDoc propName = creatorPropNames[i];
128                     for (int j=0; j < properties.length; j++)
129                         if (properties[j].getName().equals(propName)) {
130                             FormCodeSupport.readPropertyExpression(
131                                                 creationExpressions[i],
132                                                 properties[j],
133                                                 allowChangesFiring);
134                             setPropertyExpression(j, creationExpressions[i]);
135                             break;
136                         }
137                 }
138                 beanExpression.setOrigin(
139                     currentCreator.getCodeOrigin(creationExpressions));
140             }
141         }
142
143         // read properties code
144
Iterator JavaDoc it = CodeStructure.getDefinedStatementsIterator(beanExpression);
145         while (it.hasNext()) {
146             CodeStatement statement = (CodeStatement) it.next();
147             for (int j=0; j < properties.length; j++) {
148                 FormProperty prop = properties[j];
149                 if (prop instanceof RADProperty) {
150                     Method propMethod = ((RADProperty)prop)
151                                 .getPropertyDescriptor().getWriteMethod();
152                     if (propMethod != null
153                         && propMethod.equals(statement.getMetaObject()))
154                     {
155                         CodeExpression propExp =
156                             statement.getStatementParameters()[0];
157                         FormCodeSupport.readPropertyExpression(
158                                             propExp,
159                                             prop,
160                                             allowChangesFiring);
161                         setPropertyExpression(j, propExp);
162                         if (beanCode != null)
163                             beanCode.addStatement(statement);
164                         break;
165                     }
166                 }
167             }
168         }
169
170         if (beanCode != null && variableStatement != null)
171             beanCode.addStatement(0, variableStatement);
172
173         readingDone = true;
174     }
175
176     public CodeExpression getCodeExpression() {
177         return beanExpression;
178     }
179
180     // creates origin and statements according to state of properties
181
public void updateCode() {
182         if (!readingDone)
183             return; // avoid interacting with reading
184

185         CreationDescriptor.Creator newCreator =
186             creationDesc != null && !forceEmptyConstructor ?
187                 creationDesc.findBestCreator(properties, creationStyle) :
188                 null;
189
190         String JavaDoc[] creatorPropNames;
191         CodeExpression[] creationExpressions;
192         if (newCreator != null) {
193             creatorPropNames = newCreator.getPropertyNames();
194             creationExpressions =
195                 new CodeExpression[newCreator.getParameterCount()];
196         }
197         else {
198             creatorPropNames = null;
199             creationExpressions = CodeStructure.EMPTY_PARAMS;
200         }
201
202         boolean anyPropertyStatement = false;
203
204         for (int i=0; i < properties.length; i++) {
205             FormProperty property = properties[i];
206             boolean removeStatement = !property.isChanged();
207
208             if (newCreator != null) {
209                 String JavaDoc propName = property.getName();
210                 for (int j=0; j < creatorPropNames.length; j++)
211                     if (creatorPropNames[j].equals(propName)) {
212                         creationExpressions[j] = getPropertyExpression(i);
213                         removeStatement = true;
214                         break;
215                     }
216             }
217
218             // code statements can be managed automatically only for
219
// writable properties of RADProperty class
220
if (!(property instanceof RADProperty))
221                 continue;
222
223             Method statementMethod = ((RADProperty)property)
224                              .getPropertyDescriptor().getWriteMethod();
225             if (statementMethod == null)
226                 continue; // not a writable property
227

228             // get all statements of beanExpression which use statementMethod
229
Iterator JavaDoc it = CodeStructure.getDefinedStatementsIterator(
230                                                        beanExpression);
231             CodeStatement[] existingStatements =
232                 CodeStructure.filterStatements(it, statementMethod);
233
234             if (removeStatement) {
235                 for (int j=0; j < existingStatements.length; j++) {
236                     CodeStatement toRemove = existingStatements[j];
237                     CodeStructure.removeStatement(toRemove);
238                     if (beanCode != null)
239                         beanCode.remove(toRemove);
240                 }
241             }
242             else {
243                 anyPropertyStatement = true;
244                 if (existingStatements.length == 0) {
245                     CodeStatement statement =
246                         CodeStructure.createStatement(
247                             beanExpression,
248                             statementMethod,
249                             new CodeExpression[] { getPropertyExpression(i) });
250
251                     if (beanCode != null)
252                         beanCode.addStatement(statement);
253                 }
254             }
255         }
256
257         if (newCreator != null) {
258             if (newCreator != currentCreator) { // creator has changed
259
currentCreator = newCreator;
260                 beanExpression.setOrigin(newCreator.getCodeOrigin(
261                                                         creationExpressions));
262             }
263         }
264         else if (newCreator != currentCreator
265                  || beanExpression.getOrigin() == null)
266         {
267             currentCreator = null;
268
269             CodeExpressionOrigin origin = null;
270             try { // use empty constructor
271
Constructor ctor = beanClass.getConstructor(new Class JavaDoc[0]);
272                 origin = CodeStructure.createOrigin(ctor, new CodeExpression[0]);
273             }
274             catch (NoSuchMethodException JavaDoc ex) {
275                 if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
276
System.out.println("[WARNING] No default constructor for " // NOI18N
277
+ beanClass.getName());
278                     ex.printStackTrace();
279                     return;
280                 }
281             }
282             beanExpression.setOrigin(origin);
283         }
284
285         if (anyPropertyStatement) {
286             if (!isVariableSet) {
287                 CodeVariable var =
288                     codeStructure.createVariableForExpression(
289                                       beanExpression, variableType, null);
290                 if (beanCode != null) {
291                     beanCode.addStatement(0, var.getAssignment(beanExpression));
292                 }
293                 isVariableSet = true;
294             }
295         }
296         else if (isVariableSet) {
297             CodeVariable var = beanExpression.getVariable();
298             if (var != null) {
299                 if (beanCode != null)
300                     beanCode.remove(var.getAssignment(beanExpression));
301                 variableType = var.getType();
302                 codeStructure.removeExpressionFromVariable(beanExpression);
303             }
304             isVariableSet = false;
305         }
306     }
307
308     private CodeExpression getPropertyExpression(int index) {
309         if (propertyExpressions == null)
310             // we suppose the bean has a constant set of properties
311
propertyExpressions = new CodeExpression[properties.length];
312
313         CodeExpression expression = propertyExpressions[index];
314         if (expression == null) {
315             FormProperty prop = properties[index];
316             expression = codeStructure.createExpression(
317                                          FormCodeSupport.createOrigin(prop));
318             propertyExpressions[index] = expression;
319         }
320
321         return expression;
322     }
323
324     private void setPropertyExpression(int index, CodeExpression propExp) {
325         if (propertyExpressions == null)
326             propertyExpressions = new CodeExpression[properties.length];
327         propertyExpressions[index] = propExp;
328     }
329 }
330
Popular Tags