KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > bridge > MemberElementImpl


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.java.bridge;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.lang.reflect.Modifier JavaDoc;
24 import java.util.List JavaDoc;
25
26 import javax.jmi.reflect.InvalidObjectException;
27
28 import org.netbeans.api.mdr.events.*;
29 import org.netbeans.jmi.javamodel.Constructor;
30 import org.openide.nodes.Node;
31 import org.openide.src.*;
32
33 import org.openide.ErrorManager;
34 import org.openide.util.Utilities;
35
36 import org.netbeans.jmi.javamodel.Feature;
37 import org.netbeans.jmi.javamodel.JavaClass;
38
39 /** Describes a main elements of java source
40  * (variables, methods and classes). Provides support
41  * for associating this element with declaring class. Adds `name' and `modifiers' properties
42  * implementation for descendant elements as well as some utility methods for type and
43  * identifier comparison that can be utilized in change detection.
44  *
45  * @author Svatopluk Dedic, Petr Hamernik, Jaroslav Tulach
46  * @version 0.1
47  * @since 24/11/2000
48  */

49 abstract class MemberElementImpl extends ElementImpl {
50
51     /** Implementation of the declaring class. It is just a shorthand for acquiring
52      * a cookie from the ClassElement.
53      */

54     protected ClassElementImpl declaringClassImpl;
55     
56     protected transient Identifier cachedName = null;
57     
58     static final long serialVersionUID =6388377681336329844L;
59     
60     // Construction
61
///////////////////////////////////////////////////////////////////////////////////
62

63     protected MemberElementImpl(DefaultLangModel model, Feature javaElement) {
64         super(model, javaElement);
65         repository.beginTrans(false);
66         try {
67             if (this.javaElement.isValid()) {
68                 String JavaDoc name = javaElement.getName ();
69                 if (name != null)
70                     cachedName = createName (name);
71             }
72         } finally {
73             repository.endTrans();
74         }
75     }
76     
77     // Public operations
78
///////////////////////////////////////////////////////////////////////////////////
79

80     protected void setParent(ElementImpl impl) {
81         if (impl instanceof ClassElementImpl) {
82             this.declaringClassImpl = (ClassElementImpl)impl;
83             repository.beginTrans(false);
84             try {
85                 if (javaElement.isValid()) {
86                     String JavaDoc name = ((Feature) javaElement).getName ();
87                     if (name != null)
88                         cachedName = createName (name);
89                 }
90             } finally {
91                 repository.endTrans();
92             }
93         }
94     }
95     
96     protected boolean parentValid() {
97         return declaringClassImpl != null && declaringClassImpl.isValid();
98     }
99
100     protected void createFromModel(Element model) throws SourceException {
101         MemberElement other = (MemberElement)model;
102         setModifiers(other.getModifiers());
103         setName(createName(other.getName().getName()));
104     }
105     
106     protected Identifier createName(String JavaDoc n) {
107         if (n==null) n="";
108         return Identifier.create(n);
109     }
110     
111         /*
112     public Node.Cookie getCookie(Class clazz) {
113         Node.Cookie ret = super.getCookie(clazz);
114         if (ret != null)
115             return ret;
116         ClassElementImpl climpl = getDeclaringImpl();
117         if (climpl != null)
118             return climpl.getCookie(clazz);
119         return null;
120     }
121          */

122
123     // Getters
124
///////////////////////////////////////////////////////////////////////////////////
125

126     /** Getter for modifiers for this element.
127     * @see java.lang.reflect.Modifier
128     * @return constants from java.lang.reflect.Modifier
129     */

130     public int getModifiers() {
131         repository.beginTrans(false);
132         try {
133             if (javaElement.isValid()) {
134                 setClassPath();
135                 return ((Feature) javaElement).getModifiers ();
136             } else {
137                 return 0;
138             }
139         } finally {
140             repository.endTrans(false);
141         }
142     }
143
144     /** Getter for name of the field.
145     * @return the name
146     */

147     public Identifier getName() {
148         repository.beginTrans(false);
149         try {
150             if (javaElement.isValid()) {
151                 setClassPath();
152                 return createName (((Feature) javaElement).getName ());
153             } else {
154                 return cachedName != null ? cachedName : Identifier.create (""); // NOI18N
155
}
156         } finally {
157             repository.endTrans(false);
158         }
159     }
160     
161     /**
162      * Extends the basic isValid with a check, whether the ClassElement itself is valid.
163      * @return true, if both the element and its decl. class are valid.
164      */

165     public boolean isValid() {
166         if (!super.isValid())
167             return false;
168         
169         ClassElementImpl impl = getDeclaringImpl();
170         return impl == null || impl.isValid();
171     }
172     
173     protected void checkWritable(boolean unsafeOp) throws SourceException {
174         SourceElementImpl source = findSource();
175         if (source != null)
176             source.checkWritable(unsafeOp);
177     }
178     
179     /**
180      * Extracts and retrieves local classes for the element.
181      * @return array of elements representing local classes.
182      */

183     public ClassElement[] getLocalClasses() {
184         // TODO: implement fetching1 of local classes based on data extracting via
185
// model and parsing support.
186
return new ClassElement[] {};
187     }
188     
189     // Setters/changers
190
///////////////////////////////////////////////////////////////////////////////////
191
/**
192      * Overriden in subsclasses so that it check model constraints on modifier value.
193      * The default implementation does nothing.
194      */

195     protected void checkModifierConstraints(int newMods) throws SourceException {
196     }
197
198     /** Overload to impose constraint over the member's name. The default implementation
199      * does nothing.
200      */

201     protected void checkNameConstraints(Identifier name) throws SourceException {
202     }
203
204     /**
205      * Resolves, or tries to resolve the type.
206      */

207     protected final Type resolveType(Type t) {
208         if (!isConstrained())
209             return t;
210         
211         if (t.isPrimitive())
212             return t;
213         return getModelImpl().resolveType(getParent(), t);
214     }
215     
216     protected final Identifier resolveIdent(Identifier i) {
217         if (i == null || !isConstrained())
218             return i;
219         return getModelImpl().resolveIdent(getParent(), i);
220     }
221     
222     protected final Identifier[] resolveIdentifiers(Identifier[] ids) {
223         if (!isConstrained())
224             return ids;
225         
226         Identifier[] newIds = null;
227         for (int i = 0; i < ids.length; i++) {
228             Identifier n = resolveIdent(ids[i]);
229             if (n == ids[i])
230                 continue;
231             if (newIds == null) {
232                 newIds = new Identifier[ids.length];
233                 System.arraycopy(ids, 0, newIds, 0, ids.length);
234             }
235             newIds[i] = n;
236         }
237         if (newIds == null)
238             return ids;
239         return newIds;
240     }
241     
242     protected Element getParent() {
243         return getDeclaringClass();
244     }
245     
246     /** Setter for modifiers for this element.
247     * @see java.lang.reflect.Modifier
248     * @param mod constants from java.lang.reflect.Modifier
249     */

250     public void setModifiers(int mod) throws SourceException {
251         checkWritable(false);
252         checkDocument();
253         repository.beginTrans (true);
254         boolean failed = true;
255         try {
256             if (javaElement.isValid()) {
257                 setClassPath();
258                 int old = getModifiers ();
259                 if (old == mod) {
260                     failed = false;
261                     return;
262                 }
263                 if (isConstrained())
264                     checkModifierConstraints(mod);
265                 PropertyChangeEvent JavaDoc evt = new PropertyChangeEvent JavaDoc(getElement(), PROP_MODIFIERS, new Integer JavaDoc(old), new Integer JavaDoc(mod));
266                 checkVetoablePropertyChange(evt);
267
268                 ((Feature) javaElement).setModifiers (mod);
269                 failed = false;
270             } else {
271                 failed = false;
272                 throwIsInvalid ();
273             }
274         } finally {
275             repository.endTrans (failed);
276         }
277     }
278     
279     protected void doSetName(Identifier id) throws SourceException {
280         
281         String JavaDoc s = id.getName();
282         PropertyChangeEvent JavaDoc evt;
283         Identifier old = getName ();
284         if (isConstrained())
285             checkNameConstraints(id);
286         /*
287         if (old != null &&
288             old.getSourceName() == id.getSourceName()) {
289             checkIsValid ();
290             return;
291         }
292          */

293         evt = new PropertyChangeEvent JavaDoc(getElement(), PROP_NAME, old, id);
294         checkVetoablePropertyChange(evt);
295         
296         
297         if (javaElement instanceof Constructor) {
298             if (!javaElement.isValid()) {
299                 throwIsInvalid();
300             }
301         } else {
302             String JavaDoc name=id.getName();
303             
304             if (javaElement instanceof JavaClass) {
305                 ((JavaClass) javaElement).setSimpleName(name);
306             } else {
307                 ((Feature) javaElement).setName (name);
308             }
309         }
310     }
311
312     /**
313      * Implementation of name change for an Element. The implementation will:<UL>
314      * <LI>check for model constraints on the name
315      * <LI>check vetoable listener acknowledges of the change
316      * <LI>ask the Binding for performing the change
317      * <LI>fire the PropertyChangedEvent.
318      * @param id new name to use with the element.
319      */

320     public void setName(Identifier id) throws SourceException {
321         checkWritable(false);
322         checkDocument();
323         boolean failed = true;
324         repository.beginTrans (true);
325         try {
326             if (javaElement.isValid()) {
327                 setClassPath();
328                 doSetName(id);
329                 failed = false;
330             } else {
331                 failed = false;
332                 throwIsInvalid ();
333             }
334         } finally {
335             repository.endTrans (failed);
336         }
337     }
338     
339     public void fireNameChange (String JavaDoc oldValue, String JavaDoc newValue) {
340         Identifier oldName = null, newName = null;
341         if (oldValue == null)
342             oldValue = "";
343         if (newValue == null)
344             newValue = "";
345         try {
346             oldName = createName (oldValue);
347         } catch (InvalidObjectException e) {
348             oldName = Identifier.create ("");
349         }
350         try {
351             newName = createName (newValue);
352         } catch (InvalidObjectException e) {
353             newName = Identifier.create ("");
354         }
355         cachedName = newName;
356         PropertyChangeEvent JavaDoc evt = new PropertyChangeEvent JavaDoc(getElement(), PROP_NAME, oldName, newName);
357         if (!oldName.equals(newName)) // [PENDING]
358
fireOwnPropertyChange(evt);
359         
360         MemberElement old = (MemberElement) cloneSelf ();
361         // MemberElement.Impl oldImpl = (MemberElement.Impl) old.getCookie (MemberElement.Impl.class);
362
try {
363             old.setName (oldName);
364         } catch (SourceException e) {
365         }
366         notifyConnectionChange (old);
367     }
368     
369     public void fireModifiersChange (Integer JavaDoc oldValue, Integer JavaDoc newValue) {
370         PropertyChangeEvent JavaDoc evt = new PropertyChangeEvent JavaDoc(getElement(), PROP_MODIFIERS, oldValue, newValue);
371         fireOwnPropertyChange(evt);
372         
373         MemberElement old = (MemberElement) cloneSelf ();
374         try {
375             old.setModifiers (oldValue.intValue ());
376         } catch (SourceException e) {
377         }
378         notifyConnectionChange (old);
379     }
380     
381     // Utility methods
382
///////////////////////////////////////////////////////////////////////////////////
383

384     /** Compares source names of the identifiers; it does not pay attention to full names
385         specified in the identifier object.
386     */

387     protected static boolean compareSourceIdentifiers(Identifier oldId, Identifier newId) {
388         if (oldId == newId)
389             return true;
390         if (oldId == null ||
391             newId == null)
392             return false;
393         if (!oldId.getSourceName().equals(newId.getSourceName())) {
394             return false;
395         }
396         int oldRes = oldId.getResolutionStatus();
397         int newRes = newId.getResolutionStatus();
398     boolean result;
399
400     result = (oldRes == newRes || newRes == Identifier.NOT_YET_RESOLVED) && oldId.getFullName().equals(newId.getFullName());
401     return result;
402     }
403
404     /** Compares types not paying attention to fully qualified names of class types.
405     */

406     protected static boolean compareSourceTypes(Type oldType, Type newType) {
407         if (oldType == newType) {
408             return true;
409         }
410         // no type was ever present ;-)
411
if ((oldType == null) || (newType == null))
412             return false;
413         // if one of the types is a primitive one, they must be the same instance to match.
414
if (oldType.isPrimitive() || newType.isPrimitive()) {
415             return false;
416         }
417         if (oldType.isArray()) {
418             if (!newType.isArray()) {
419                 return false;
420             }
421             return compareSourceTypes(oldType.getElementType(), newType.getElementType());
422         } else if (newType.isArray()) {
423             return false;
424         }
425         if (!oldType.isClass() || !newType.isClass()) {
426             throw new InternalError JavaDoc("Unexpected type combination."); // NOI18N
427
}
428         return compareSourceIdentifiers(oldType.getTypeIdentifier(),
429             newType.getTypeIdentifier());
430     }
431
432     /**
433      * Members source finder delegates to the class' one.
434      */

435     protected SourceElementImpl findSource() {
436         if (this.declaringClassImpl != null)
437             return this.declaringClassImpl.findSource();
438         else
439             return null;
440     }
441
442     /**
443      * Returns the implementation of the declaring class.
444      */

445     protected ClassElementImpl getDeclaringImpl() {
446         return this.declaringClassImpl;
447     }
448     
449     /** Returns the abstract layer for the declaring class implementation.
450      */

451     protected ClassElement getDeclaringClass() {
452         if (declaringClassImpl == null)
453             return null;
454         return (ClassElement)declaringClassImpl.getElement();
455     }
456     
457     /**
458      * Access method to the Element's isValid, may be used by subclasses for overriding
459      * isValid semantics.
460      */

461     protected boolean isElementValid() {
462         return super.isValid();
463     }
464
465     void updateJavadoc() {
466         try {
467             String JavaDoc javadocText=((Feature)javaElement).getJavadocText();
468             if (!Utilities.compareObjects(javadocText, javadoc.getRawText())) {
469                 try {
470                     javadoc.changeJavaDocText(javadocText, true);
471                 } catch (SourceException ex) {
472                     ErrorManager.getDefault().notify(ex);
473                 }
474             }
475         } catch (InvalidObjectException e) {
476         }
477     }
478     // ..........................................................................
479

480     static class MemberElementListener extends ElementImpl.ElementListener {
481         
482         MemberElementListener (MemberElementImpl impl) {
483             super (impl);
484         }
485
486         public void doChange (MDRChangeEvent event) {
487             super.doChange (event);
488             if ((source == javaElement) && (event instanceof AttributeEvent)) {
489                 AttributeEvent attrEvent = (AttributeEvent) event;
490                 String JavaDoc attrName = attrEvent.getAttributeName ();
491                 if (attrName.equals ("name")) { // NOI18N
492
((MemberElementImpl) impl).fireNameChange (
493                         (String JavaDoc) attrEvent.getOldElement (),
494                         (String JavaDoc) attrEvent.getNewElement ()
495                      );
496                 } else if (attrName.equals ("modifiers")) { // NOI18N
497
((MemberElementImpl) impl).fireModifiersChange (
498                         (Integer JavaDoc) attrEvent.getOldElement (),
499                         (Integer JavaDoc) attrEvent.getNewElement ()
500                      );
501                 }
502             }
503         }
504         
505     }
506     
507 }
508
Popular Tags