001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.beans;
043:
044: import java.awt.Image;
045: import javax.lang.model.element.ExecutableElement;
046: import javax.lang.model.type.TypeMirror;
047: import org.netbeans.api.java.source.ElementHandle;
048: import org.netbeans.api.java.source.TypeMirrorHandle;
049:
050: /** EventSetPattern: This class holds the information about used event set pattern
051: * in code.
052: * @author Petr Hrebejk
053: *
054: *
055: * PENDING: Add Pattern class hierarchy (abstract classes || interfaces )
056: */
057: public final class EventSetPattern extends Pattern {
058:
059: protected ElementHandle<ExecutableElement> addListenerMethod;
060: protected ElementHandle<ExecutableElement> removeListenerMethod;
061: protected boolean isUnicast;
062:
063: // Constructors ------------------------------------------------------------
064:
065: public EventSetPattern(PatternAnalyser patternAnalyser,
066: ExecutableElement addListenerMethod,
067: ExecutableElement removeListenerMethod, String name,
068: TypeMirror type, boolean isUnicast) {
069: super (patternAnalyser, Pattern.Kind.EVENT_SOURCE, name,
070: TypeMirrorHandle.create(type));
071: this .addListenerMethod = addListenerMethod == null ? null
072: : ElementHandle.create(addListenerMethod);
073: this .removeListenerMethod = removeListenerMethod == null ? null
074: : ElementHandle.create(removeListenerMethod);
075: this .isUnicast = isUnicast;
076: }
077:
078: // EventSetPattern( PatternAnalyser analyser ) {
079: // super( analyser );
080: // }
081:
082: // Getters and setters -----------------------------------------------------
083:
084: @Override
085: public Image getIcon() {
086: return isUnicast() ? EVENT_SET_UNICAST : EVENT_SET_MULTICAST;
087: }
088:
089: @Override
090: public String getHtmlDisplayName() {
091: return null;
092: }
093:
094: /** Returns the getter method */
095: public ElementHandle<ExecutableElement> getAddListenerMethod() {
096: return addListenerMethod;
097: }
098:
099: /** Returns the setter method */
100: public ElementHandle<ExecutableElement> getRemoveListenerMethod() {
101: return removeListenerMethod;
102: }
103:
104: /** Returns the mode of the property READ_WRITE, READ_ONLY or WRITE_ONLY */
105: public boolean isUnicast() {
106: return isUnicast;
107: }
108:
109: /** Sets the name of PropertyPattern */
110: public void setName(String name) /* throws IllegalArgumentException */{
111: throw new UnsupportedOperationException();
112:
113: // if ( !Utilities.isJavaIdentifier( name ) || name.indexOf( "Listener" ) <= 0 ) // NOI18N
114: // throw new IllegalArgumentException( "Invalid event source name" ); // NOI18N
115: //
116: // name = capitalizeFirstLetter( name );
117: //
118: // String addMethodID = "add" + name; // NOI18N
119: // String removeMethodID = "remove" + name; // NOI18N
120: //
121: // JMIUtils.beginTrans(true);
122: // boolean rollback = true;
123: // try {
124: // if (addListenerMethod.isValid() && removeListenerMethod.isValid()) {
125: // addListenerMethod.setName( addMethodID );
126: // removeListenerMethod.setName( removeMethodID );
127: // this.name = Introspector.decapitalize( name );
128: // }
129: // rollback = false;
130: // } finally {
131: // JMIUtils.endTrans(rollback);
132: // }
133: }
134:
135: //
136: // /** Creates new pattern from result of dialog */
137: // static EventSetPattern create( PatternAnalyser patternAnalyser,
138: // String type,
139: // int implementation,
140: // boolean fire,
141: // boolean passEvent,
142: // boolean isUnicast ) {
143: //
144: // assert JMIUtils.isInsideTrans();
145: // EventSetPattern esp = new EventSetPattern( patternAnalyser );
146: //
147: // esp.type = patternAnalyser.findType(type);
148: //
149: // if ( esp.type == null || !(esp.type instanceof JavaClass)) {
150: // return null;
151: // }
152: //
153: // //System.out.println( "Type " + esp.type.toString() ); // NOI18N
154: //
155: //
156: // esp.name = Introspector.decapitalize( ((JavaClass) esp.type).getSimpleName() );
157: // esp.isUnicast = isUnicast;
158: //
159: // String listenerList = null;
160: //
161: // if ( implementation == 1 ) {
162: // if ( isUnicast )
163: // BeanPatternGenerator.unicastListenerField( esp.getDeclaringClass(), esp.type, true);
164: // else
165: // BeanPatternGenerator.listenersArrayListField( esp.getDeclaringClass(), esp.type, true );
166: // }
167: // else if ( implementation == 2 && !isUnicast ) {
168: // listenerList = BeanPatternGenerator.eventListenerListField( esp.getDeclaringClass(), esp.type, true).getName();
169: // }
170: //
171: //
172: // if ( isUnicast ) {
173: // esp.generateAddListenerMethod( BeanPatternGenerator.ucAddBody( esp.type, implementation ), true );
174: // esp.generateRemoveListenerMethod( BeanPatternGenerator.ucRemoveBody( esp.type, implementation ), true );
175: // }
176: // else {
177: // esp.generateAddListenerMethod( BeanPatternGenerator.mcAddBody( esp.type, implementation, listenerList ), true );
178: // esp.generateRemoveListenerMethod( BeanPatternGenerator.mcRemoveBody( esp.type, implementation, listenerList ), true );
179: // }
180: //
181: // if ( fire ) {
182: // JavaClass listener = (JavaClass) esp.type;
183: //
184: // List/*<Method>*/ methods = JMIUtils.getMethods(listener);
185: // boolean isInterface = listener.isInterface();
186: // for (Iterator it = methods.iterator(); it.hasNext();) {
187: // Method method = (Method) it.next();
188: // if ( ((method.getModifiers() & Modifier.PUBLIC) != 0 ) ||
189: // (isInterface && (method.getModifiers() & (Modifier.PROTECTED | Modifier.PRIVATE)) == 0)
190: // ) {
191: // if ( isUnicast )
192: // BeanPatternGenerator.unicastFireMethod( esp.getDeclaringClass(), esp.type,
193: // method, implementation, passEvent );
194: // else
195: // BeanPatternGenerator.fireMethod( esp.getDeclaringClass(), esp.type,
196: // method, implementation, listenerList, passEvent );
197: // }
198: // }
199: // }
200: //
201: //
202: // return esp;
203: // }
204: //
205: // private Field getEstimatedListenerField() {
206: // Field f;
207: // if ( isUnicast )
208: // f = BeanPatternGenerator.unicastListenerField( getDeclaringClass(), getType(), false);
209: // else {
210: // f = BeanPatternGenerator.listenersArrayListField( getDeclaringClass(), getType(), false);
211: // if (f==null) {
212: // f = BeanPatternGenerator.eventListenerListField( getDeclaringClass(), getType(), false);
213: // }
214: // }
215: // return f;
216: // }
217: //
218: // /** Test if the name is valid for given pattern */
219: // protected static boolean isValidName( String str ) {
220: // if ( Utilities.isJavaIdentifier(str) == false )
221: // return false;
222: //
223: // if (str.indexOf( "Listener" ) <= 0 ) // NOI18N
224: // return false;
225: //
226: // return true;
227: // }
228: //
229: //
230: //
231: // /** Sets the property to be unicast or multicast */
232: // public void setIsUnicast( boolean b ) throws JmiException {
233: // if ( b == isUnicast) {
234: // return;
235: // }
236: //
237: // JMIUtils.beginTrans(true);
238: // boolean rollback = true;
239: // try {
240: // if (!addListenerMethod.isValid()) {
241: // return;
242: // }
243: // List/*<MultipartId>*/ exs = addListenerMethod.getExceptionNames();
244: //
245: // if (b) {
246: // JavaModelPackage jmodel = JavaMetamodel.getManager().getJavaExtent(addListenerMethod);
247: // MultipartId tooManyId = jmodel.getMultipartId().
248: // createMultipartId("java.util.TooManyListenersException", null, null); // NOI18N
249: // exs.add(tooManyId);
250: // } else {
251: // JavaClass tooMany = patternAnalyser.findClassElement("java.util.TooManyListenersException"); // NOI18N
252: // assert tooMany != null;
253: // List/*<MultipartId>*/ remove = new LinkedList/*<MultipartId>*/();
254: // for (Iterator it = exs.iterator(); it.hasNext();) {
255: // MultipartId exId = (MultipartId) it.next();
256: // JavaClass ex = (JavaClass) exId.getElement();
257: // if (tooMany.isSubTypeOf(ex)) {
258: // remove.add(exId);
259: // }
260: // }
261: // exs.removeAll(remove);
262: // }
263: //
264: // this.isUnicast = b;
265: // rollback = false;
266: // } finally {
267: // JMIUtils.endTrans(rollback);
268: // }
269: // }
270: //
271: //
272: //
273: // /** Sets the type of property */
274: // public void setType( Type newType ) throws JmiException {
275: // int state = 0;
276: // JMIUtils.beginTrans(true);
277: // boolean rollback = true;
278: // try {
279: // if (this.type.equals(newType) || !newType.isValid())
280: // return;
281: //
282: // if (!(newType instanceof JavaClass) ||
283: // !PatternAnalyser.isSubclass((JavaClass) newType,
284: // patternAnalyser.findClassElement("java.util.EventListener"))) { // NOI18N
285: //
286: // state = 1;
287: // } else {
288: // JavaModelPackage jmodel = (JavaModelPackage) addListenerMethod.refImmediatePackage();
289: //
290: // String newTypeName = ((JavaClass) newType).getSimpleName();
291: // List/*<Parameter>*/ params = addListenerMethod.getParameters();
292: // params.clear();
293: // Parameter newParameter = jmodel.getParameter().createParameter();
294: // newParameter.setName("listener"); // NOI18N
295: // newParameter.setType(newType);
296: // params.add(newParameter);
297: //
298: // params = removeListenerMethod.getParameters();
299: // params.clear();
300: // newParameter = jmodel.getParameter().createParameter();
301: // newParameter.setName("listener"); // NOI18N
302: // newParameter.setType(newType);
303: // params.add(newParameter);
304: //
305: // // Ask if we have to change the bame of the methods
306: // String msg = MessageFormat.format(PatternNode.getString("FMT_ChangeEventSourceName"), // NOI18N
307: // new Object[]{capitalizeFirstLetter(newTypeName)});
308: // NotifyDescriptor nd = new NotifyDescriptor.Confirmation(msg, NotifyDescriptor.YES_NO_OPTION);
309: // if (DialogDisplayer.getDefault().notify(nd).equals(NotifyDescriptor.YES_OPTION)) {
310: // setName(newTypeName);
311: // }
312: //
313: // this.type = newType;
314: // }
315: //
316: // rollback = false;
317: // } finally {
318: // JMIUtils.endTrans(rollback);
319: // }
320: // switch(state) {
321: // case 1:
322: // DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(PatternNode.getString("MSG_InvalidListenerInterface"), // NOI18N
323: // NotifyDescriptor.ERROR_MESSAGE));
324: // break;
325: //
326: // }
327: // }
328: //
329: // /** Gets the cookie of the first available method */
330: // public Node.Cookie getCookie( Class cookieType ) {
331: // return super.getCookie(cookieType);
332: // }
333: //
334: // public void destroy() throws JmiException {
335: // assert JMIUtils.isInsideTrans();
336: // if ( addListenerMethod != null && addListenerMethod.isValid() ) {
337: // addListenerMethod.refDelete();
338: // }
339: //
340: // if ( removeListenerMethod != null && removeListenerMethod.isValid() ) {
341: // removeListenerMethod.refDelete();
342: // }
343: //
344: // //** BOB - Matula
345: //
346: // // delete associated "fire" methods
347: // JavaClass declaringClass = getDeclaringClass();
348: // JavaClass listener = (JavaClass) type;
349: // boolean canDelete = false;
350: //
351: // if ( listener != null ) {
352: // List methods = JMIUtils.getMethods(listener);
353: // List sourceMethods = JMIUtils.getMethods(declaringClass);
354: // String method;
355: // String typeName = listener.getSimpleName();
356: //
357: // for (Iterator it = methods.iterator(); it.hasNext();) {
358: // Method lsnrMethod = (Method) it.next();
359: // method = "fire" + // NOI18N
360: // Pattern.capitalizeFirstLetter(typeName) +
361: // Pattern.capitalizeFirstLetter(lsnrMethod.getName());
362: // if (Modifier.isPublic(lsnrMethod.getModifiers())) {
363: // for (Iterator it2 = sourceMethods.iterator(); it2.hasNext();) {
364: // Method srcMethod = (Method) it2.next();
365: // if (srcMethod.isValid() && srcMethod.getName().equals(method)) {
366: // if (!canDelete) {
367: // // Ask, if the fire methods can be deleted
368: // String mssg = MessageFormat.format( PatternNode.getString( "FMT_DeleteFire" ),
369: // new Object[0] );
370: // NotifyDescriptor nd = new NotifyDescriptor.Confirmation ( mssg, NotifyDescriptor.YES_NO_OPTION );
371: // if ( DialogDisplayer.getDefault().notify( nd ).equals( NotifyDescriptor.NO_OPTION ) ) {
372: // return;
373: // } else {
374: // canDelete = true;
375: // }
376: // }
377: // srcMethod.refDelete();
378: // }
379: // }
380: // }
381: // }
382: // }
383: // //** EOB - Matula
384: // Field field = getEstimatedListenerField();
385: // if ( field != null && field.isValid() && field.getReferences().isEmpty()) {
386: // field.refDelete();
387: // }
388: // }
389: //
390: // // Utility methods --------------------------------------------------------------------
391: //
392: //
393: //
394: // void generateAddListenerMethod ( String body, boolean javadoc ) throws JmiException {
395: // assert JMIUtils.isInsideTrans();
396: // JavaClass declaringClass = getDeclaringClass();
397: // if ( declaringClass == null )
398: // throw new IllegalStateException("Missing declaring class"); // NOI18N
399: //
400: // JavaModelPackage jmodel = JavaMetamodel.getManager().getJavaExtent(declaringClass);
401: // Method newMethod = jmodel.getMethod().createMethod();
402: // int modifiers = Modifier.PUBLIC | Modifier.SYNCHRONIZED;
403: // Parameter newParameter = jmodel.getParameter().createParameter();
404: // newParameter.setName("listener"); // NOI18N
405: // newParameter.setType(type);
406: //
407: // newMethod.setName( "add" + capitalizeFirstLetter( getName() ) ); // NOI18N
408: // newMethod.setTypeName(jmodel.getMultipartId().createMultipartId("void", null, null)); // NOI18N
409: // List/*<Parameter>*/ params = newMethod.getParameters();
410: // params.add(newParameter);
411: //
412: // if ( declaringClass.isInterface() ) {
413: // modifiers &= ~Modifier.SYNCHRONIZED; // synchronized modifier is not allowed in interface
414: // } else if ( body != null )
415: // newMethod.setBodyText( body );
416: // newMethod.setModifiers( modifiers );
417: // if ( isUnicast ) {
418: // MultipartId tooManyLsnrs = jmodel.getMultipartId().
419: // createMultipartId("java.util.TooManyListenersException", null, null); // NOI18N
420: // newMethod.getExceptionNames().add(tooManyLsnrs);
421: // }
422: // if ( javadoc ) {
423: // String comment = MessageFormat.format( PatternNode.getString( "COMMENT_AddListenerMethod" ),
424: // new Object[] { ((JavaClass) type).getSimpleName() } );
425: // newMethod.setJavadocText( comment );
426: // }
427: //
428: // declaringClass.getContents().add(newMethod);
429: // addListenerMethod = newMethod;
430: // }
431: //
432: // void generateRemoveListenerMethod( String body, boolean javadoc ) throws JmiException {
433: // assert JMIUtils.isInsideTrans();
434: // JavaClass declaringClass = getDeclaringClass();
435: // if ( declaringClass == null )
436: // throw new IllegalStateException("Missing declaring class"); // NOI18N
437: //
438: // JavaModelPackage jmodel = JavaMetamodel.getManager().getJavaExtent(declaringClass);
439: // Method newMethod = jmodel.getMethod().createMethod();
440: // int modifiers = Modifier.PUBLIC | Modifier.SYNCHRONIZED;
441: // Parameter newParameter = jmodel.getParameter().createParameter();
442: // newParameter.setName("listener"); // NOI18N
443: // newParameter.setType(type);
444: //
445: // newMethod.setName( "remove" + capitalizeFirstLetter( getName() ) ); // NOI18N
446: // newMethod.setTypeName(jmodel.getMultipartId().createMultipartId("void", null, null)); // NOI18N
447: // List/*<Parameter>*/ params = newMethod.getParameters();
448: // params.add(newParameter);
449: //
450: // if ( declaringClass.isInterface() ) {
451: // modifiers &= ~Modifier.SYNCHRONIZED; // synchronized modifier is not allowed in interface
452: // } else if ( body != null )
453: // newMethod.setBodyText( body );
454: // newMethod.setModifiers( modifiers );
455: // if ( javadoc ) {
456: // String comment = MessageFormat.format( PatternNode.getString( "COMMENT_RemoveListenerMethod" ),
457: // new Object[] { ((JavaClass) type).getSimpleName() } );
458: // newMethod.setJavadocText( comment );
459: // }
460: //
461: // declaringClass.getContents().add(newMethod);
462: // removeListenerMethod = newMethod;
463: // }
464: //
465: // // Property change support -------------------------------------------------------------------------
466: //
467: // void copyProperties( EventSetPattern src ) throws JmiException {
468: // assert JMIUtils.isInsideTrans();
469: // boolean changed = !src.getType().equals( getType() ) ||
470: // !src.getName().equals( getName() ) ||
471: // !(src.isUnicast() == isUnicast());
472: //
473: // if ( src.getAddListenerMethod() != addListenerMethod )
474: // addListenerMethod = src.getAddListenerMethod();
475: // if ( src.getRemoveListenerMethod() != removeListenerMethod )
476: // removeListenerMethod = src.getRemoveListenerMethod();
477: //
478: // if ( changed ) {
479: //
480: // isUnicast = testUnicast();
481: //
482: // findEventSetType();
483: // isUnicast = testUnicast();
484: // name = findEventSetName();
485: //
486: // // XXX cannot be fired inside mdr transaction; post to dedicated thread or redesigne somehow
487: // firePropertyChange( new java.beans.PropertyChangeEvent( this, null, null, null ) );
488: // }
489: //
490: // }
491:
492: }
|