| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.beans; |
| |
| import java.awt.Image; |
| import javax.lang.model.element.ExecutableElement; |
| import javax.lang.model.type.TypeMirror; |
| import org.netbeans.api.java.source.ElementHandle; |
| import org.netbeans.api.java.source.TypeMirrorHandle; |
| |
| /** EventSetPattern: This class holds the information about used event set pattern |
| * in code. |
| * @author Petr Hrebejk |
| * |
| * |
| * PENDING: Add Pattern class hierarchy (abstract classes || interfaces ) |
| */ |
| public final class EventSetPattern extends Pattern { |
| |
| protected ElementHandle<ExecutableElement> addListenerMethod; |
| protected ElementHandle<ExecutableElement> removeListenerMethod; |
| protected boolean isUnicast; |
| |
| // Constructors ------------------------------------------------------------ |
| |
| public EventSetPattern(PatternAnalyser patternAnalyser, |
| ExecutableElement addListenerMethod, |
| ExecutableElement removeListenerMethod, |
| String name, |
| TypeMirror type, |
| boolean isUnicast ) { |
| super( patternAnalyser, Pattern.Kind.EVENT_SOURCE, name, TypeMirrorHandle.create(type) ); |
| this.addListenerMethod = addListenerMethod == null ? null : ElementHandle.create(addListenerMethod); |
| this.removeListenerMethod = removeListenerMethod == null ? null : ElementHandle.create(removeListenerMethod); |
| this.isUnicast = isUnicast; |
| } |
| |
| // EventSetPattern( PatternAnalyser analyser ) { |
| // super( analyser ); |
| // } |
| |
| // Getters and setters ----------------------------------------------------- |
| |
| @Override |
| public Image getIcon() { |
| return isUnicast() ? EVENT_SET_UNICAST : EVENT_SET_MULTICAST; |
| } |
| |
| @Override |
| public String getHtmlDisplayName() { |
| return null; |
| } |
| |
| /** Returns the getter method */ |
| public ElementHandle<ExecutableElement> getAddListenerMethod() { |
| return addListenerMethod; |
| } |
| |
| /** Returns the setter method */ |
| public ElementHandle<ExecutableElement> getRemoveListenerMethod() { |
| return removeListenerMethod; |
| } |
| |
| |
| /** Returns the mode of the property READ_WRITE, READ_ONLY or WRITE_ONLY */ |
| public boolean isUnicast() { |
| return isUnicast; |
| } |
| |
| /** Sets the name of PropertyPattern */ |
| public void setName( String name ) /* throws IllegalArgumentException */ { |
| throw new UnsupportedOperationException(); |
| |
| // if ( !Utilities.isJavaIdentifier( name ) || name.indexOf( "Listener" ) <= 0 ) // NOI18N |
| // throw new IllegalArgumentException( "Invalid event source name" ); // NOI18N |
| // |
| // name = capitalizeFirstLetter( name ); |
| // |
| // String addMethodID = "add" + name; // NOI18N |
| // String removeMethodID = "remove" + name; // NOI18N |
| // |
| // JMIUtils.beginTrans(true); |
| // boolean rollback = true; |
| // try { |
| // if (addListenerMethod.isValid() && removeListenerMethod.isValid()) { |
| // addListenerMethod.setName( addMethodID ); |
| // removeListenerMethod.setName( removeMethodID ); |
| // this.name = Introspector.decapitalize( name ); |
| // } |
| // rollback = false; |
| // } finally { |
| // JMIUtils.endTrans(rollback); |
| // } |
| } |
| |
| |
| |
| |
| // |
| // /** Creates new pattern from result of dialog */ |
| // static EventSetPattern create( PatternAnalyser patternAnalyser, |
| // String type, |
| // int implementation, |
| // boolean fire, |
| // boolean passEvent, |
| // boolean isUnicast ) { |
| // |
| // assert JMIUtils.isInsideTrans(); |
| // EventSetPattern esp = new EventSetPattern( patternAnalyser ); |
| // |
| // esp.type = patternAnalyser.findType(type); |
| // |
| // if ( esp.type == null || !(esp.type instanceof JavaClass)) { |
| // return null; |
| // } |
| // |
| // //System.out.println( "Type " + esp.type.toString() ); // NOI18N |
| // |
| // |
| // esp.name = Introspector.decapitalize( ((JavaClass) esp.type).getSimpleName() ); |
| // esp.isUnicast = isUnicast; |
| // |
| // String listenerList = null; |
| // |
| // if ( implementation == 1 ) { |
| // if ( isUnicast ) |
| // BeanPatternGenerator.unicastListenerField( esp.getDeclaringClass(), esp.type, true); |
| // else |
| // BeanPatternGenerator.listenersArrayListField( esp.getDeclaringClass(), esp.type, true ); |
| // } |
| // else if ( implementation == 2 && !isUnicast ) { |
| // listenerList = BeanPatternGenerator.eventListenerListField( esp.getDeclaringClass(), esp.type, true).getName(); |
| // } |
| // |
| // |
| // if ( isUnicast ) { |
| // esp.generateAddListenerMethod( BeanPatternGenerator.ucAddBody( esp.type, implementation ), true ); |
| // esp.generateRemoveListenerMethod( BeanPatternGenerator.ucRemoveBody( esp.type, implementation ), true ); |
| // } |
| // else { |
| // esp.generateAddListenerMethod( BeanPatternGenerator.mcAddBody( esp.type, implementation, listenerList ), true ); |
| // esp.generateRemoveListenerMethod( BeanPatternGenerator.mcRemoveBody( esp.type, implementation, listenerList ), true ); |
| // } |
| // |
| // if ( fire ) { |
| // JavaClass listener = (JavaClass) esp.type; |
| // |
| // List/*<Method>*/ methods = JMIUtils.getMethods(listener); |
| // boolean isInterface = listener.isInterface(); |
| // for (Iterator it = methods.iterator(); it.hasNext();) { |
| // Method method = (Method) it.next(); |
| // if ( ((method.getModifiers() & Modifier.PUBLIC) != 0 ) || |
| // (isInterface && (method.getModifiers() & (Modifier.PROTECTED | Modifier.PRIVATE)) == 0) |
| // ) { |
| // if ( isUnicast ) |
| // BeanPatternGenerator.unicastFireMethod( esp.getDeclaringClass(), esp.type, |
| // method, implementation, passEvent ); |
| // else |
| // BeanPatternGenerator.fireMethod( esp.getDeclaringClass(), esp.type, |
| // method, implementation, listenerList, passEvent ); |
| // } |
| // } |
| // } |
| // |
| // |
| // return esp; |
| // } |
| // |
| // private Field getEstimatedListenerField() { |
| // Field f; |
| // if ( isUnicast ) |
| // f = BeanPatternGenerator.unicastListenerField( getDeclaringClass(), getType(), false); |
| // else { |
| // f = BeanPatternGenerator.listenersArrayListField( getDeclaringClass(), getType(), false); |
| // if (f==null) { |
| // f = BeanPatternGenerator.eventListenerListField( getDeclaringClass(), getType(), false); |
| // } |
| // } |
| // return f; |
| // } |
| // |
| // /** Test if the name is valid for given pattern */ |
| // protected static boolean isValidName( String str ) { |
| // if ( Utilities.isJavaIdentifier(str) == false ) |
| // return false; |
| // |
| // if (str.indexOf( "Listener" ) <= 0 ) // NOI18N |
| // return false; |
| // |
| // return true; |
| // } |
| // |
| // |
| // |
| // /** Sets the property to be unicast or multicast */ |
| // public void setIsUnicast( boolean b ) throws JmiException { |
| // if ( b == isUnicast) { |
| // return; |
| // } |
| // |
| // JMIUtils.beginTrans(true); |
| // boolean rollback = true; |
| // try { |
| // if (!addListenerMethod.isValid()) { |
| // return; |
| // } |
| // List/*<MultipartId>*/ exs = addListenerMethod.getExceptionNames(); |
| // |
| // if (b) { |
| // JavaModelPackage jmodel = JavaMetamodel.getManager().getJavaExtent(addListenerMethod); |
| // MultipartId tooManyId = jmodel.getMultipartId(). |
| // createMultipartId("java.util.TooManyListenersException", null, null); // NOI18N |
| // exs.add(tooManyId); |
| // } else { |
| // JavaClass tooMany = patternAnalyser.findClassElement("java.util.TooManyListenersException"); // NOI18N |
| // assert tooMany != null; |
| // List/*<MultipartId>*/ remove = new LinkedList/*<MultipartId>*/(); |
| // for (Iterator it = exs.iterator(); it.hasNext();) { |
| // MultipartId exId = (MultipartId) it.next(); |
| // JavaClass ex = (JavaClass) exId.getElement(); |
| // if (tooMany.isSubTypeOf(ex)) { |
| // remove.add(exId); |
| // } |
| // } |
| // exs.removeAll(remove); |
| // } |
| // |
| // this.isUnicast = b; |
| // rollback = false; |
| // } finally { |
| // JMIUtils.endTrans(rollback); |
| // } |
| // } |
| // |
| // |
| // |
| // /** Sets the type of property */ |
| // public void setType( Type newType ) throws JmiException { |
| // int state = 0; |
| // JMIUtils.beginTrans(true); |
| // boolean rollback = true; |
| // try { |
| // if (this.type.equals(newType) || !newType.isValid()) |
| // return; |
| // |
| // if (!(newType instanceof JavaClass) || |
| // !PatternAnalyser.isSubclass((JavaClass) newType, |
| // patternAnalyser.findClassElement("java.util.EventListener"))) { // NOI18N |
| // |
| // state = 1; |
| // } else { |
| // JavaModelPackage jmodel = (JavaModelPackage) addListenerMethod.refImmediatePackage(); |
| // |
| // String newTypeName = ((JavaClass) newType).getSimpleName(); |
| // List/*<Parameter>*/ params = addListenerMethod.getParameters(); |
| // params.clear(); |
| // Parameter newParameter = jmodel.getParameter().createParameter(); |
| // newParameter.setName("listener"); // NOI18N |
| // newParameter.setType(newType); |
| // params.add(newParameter); |
| // |
| // params = removeListenerMethod.getParameters(); |
| // params.clear(); |
| // newParameter = jmodel.getParameter().createParameter(); |
| // newParameter.setName("listener"); // NOI18N |
| // newParameter.setType(newType); |
| // params.add(newParameter); |
| // |
| // // Ask if we have to change the bame of the methods |
| // String msg = MessageFormat.format(PatternNode.getString("FMT_ChangeEventSourceName"), // NOI18N |
| // new Object[]{capitalizeFirstLetter(newTypeName)}); |
| // NotifyDescriptor nd = new NotifyDescriptor.Confirmation(msg, NotifyDescriptor.YES_NO_OPTION); |
| // if (DialogDisplayer.getDefault().notify(nd).equals(NotifyDescriptor.YES_OPTION)) { |
| // setName(newTypeName); |
| // } |
| // |
| // this.type = newType; |
| // } |
| // |
| // rollback = false; |
| // } finally { |
| // JMIUtils.endTrans(rollback); |
| // } |
| // switch(state) { |
| // case 1: |
| // DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(PatternNode.getString("MSG_InvalidListenerInterface"), // NOI18N |
| // NotifyDescriptor.ERROR_MESSAGE)); |
| // break; |
| // |
| // } |
| // } |
| // |
| // /** Gets the cookie of the first available method */ |
| // public Node.Cookie getCookie( Class cookieType ) { |
| // return super.getCookie(cookieType); |
| // } |
| // |
| // public void destroy() throws JmiException { |
| // assert JMIUtils.isInsideTrans(); |
| // if ( addListenerMethod != null && addListenerMethod.isValid() ) { |
| // addListenerMethod.refDelete(); |
| // } |
| // |
| // if ( removeListenerMethod != null && removeListenerMethod.isValid() ) { |
| // removeListenerMethod.refDelete(); |
| // } |
| // |
| // //** BOB - Matula |
| // |
| // // delete associated "fire" methods |
| // JavaClass declaringClass = getDeclaringClass(); |
| // JavaClass listener = (JavaClass) type; |
| // boolean canDelete = false; |
| // |
| // if ( listener != null ) { |
| // List methods = JMIUtils.getMethods(listener); |
| // List sourceMethods = JMIUtils.getMethods(declaringClass); |
| // String method; |
| // String typeName = listener.getSimpleName(); |
| // |
| // for (Iterator it = methods.iterator(); it.hasNext();) { |
| // Method lsnrMethod = (Method) it.next(); |
| // method = "fire" + // NOI18N |
| // Pattern.capitalizeFirstLetter(typeName) + |
| // Pattern.capitalizeFirstLetter(lsnrMethod.getName()); |
| // if (Modifier.isPublic(lsnrMethod.getModifiers())) { |
| // for (Iterator it2 = sourceMethods.iterator(); it2.hasNext();) { |
| // Method srcMethod = (Method) it2.next(); |
| // if (srcMethod.isValid() && srcMethod.getName().equals(method)) { |
| // if (!canDelete) { |
| // // Ask, if the fire methods can be deleted |
| // String mssg = MessageFormat.format( PatternNode.getString( "FMT_DeleteFire" ), |
| // new Object[0] ); |
| // NotifyDescriptor nd = new NotifyDescriptor.Confirmation ( mssg, NotifyDescriptor.YES_NO_OPTION ); |
| // if ( DialogDisplayer.getDefault().notify( nd ).equals( NotifyDescriptor.NO_OPTION ) ) { |
| // return; |
| // } else { |
| // canDelete = true; |
| // } |
| // } |
| // srcMethod.refDelete(); |
| // } |
| // } |
| // } |
| // } |
| // } |
| // //** EOB - Matula |
| // Field field = getEstimatedListenerField(); |
| // if ( field != null && field.isValid() && field.getReferences().isEmpty()) { |
| // field.refDelete(); |
| // } |
| // } |
| // |
| // // Utility methods -------------------------------------------------------------------- |
| // |
| // |
| // |
| // void generateAddListenerMethod ( String body, boolean javadoc ) throws JmiException { |
| // assert JMIUtils.isInsideTrans(); |
| // JavaClass declaringClass = getDeclaringClass(); |
| // if ( declaringClass == null ) |
| // throw new IllegalStateException("Missing declaring class"); // NOI18N |
| // |
| // JavaModelPackage jmodel = JavaMetamodel.getManager().getJavaExtent(declaringClass); |
| // Method newMethod = jmodel.getMethod().createMethod(); |
| // int modifiers = Modifier.PUBLIC | Modifier.SYNCHRONIZED; |
| // Parameter newParameter = jmodel.getParameter().createParameter(); |
| // newParameter.setName("listener"); // NOI18N |
| // newParameter.setType(type); |
| // |
| // newMethod.setName( "add" + capitalizeFirstLetter( getName() ) ); // NOI18N |
| // newMethod.setTypeName(jmodel.getMultipartId().createMultipartId("void", null, null)); // NOI18N |
| // List/*<Parameter>*/ params = newMethod.getParameters(); |
| // params.add(newParameter); |
| // |
| // if ( declaringClass.isInterface() ) { |
| // modifiers &= ~Modifier.SYNCHRONIZED; // synchronized modifier is not allowed in interface |
| // } else if ( body != null ) |
| // newMethod.setBodyText( body ); |
| // newMethod.setModifiers( modifiers ); |
| // if ( isUnicast ) { |
| // MultipartId tooManyLsnrs = jmodel.getMultipartId(). |
| // createMultipartId("java.util.TooManyListenersException", null, null); // NOI18N |
| // newMethod.getExceptionNames().add(tooManyLsnrs); |
| // } |
| // if ( javadoc ) { |
| // String comment = MessageFormat.format( PatternNode.getString( "COMMENT_AddListenerMethod" ), |
| // new Object[] { ((JavaClass) type).getSimpleName() } ); |
| // newMethod.setJavadocText( comment ); |
| // } |
| // |
| // declaringClass.getContents().add(newMethod); |
| // addListenerMethod = newMethod; |
| // } |
| // |
| // void generateRemoveListenerMethod( String body, boolean javadoc ) throws JmiException { |
| // assert JMIUtils.isInsideTrans(); |
| // JavaClass declaringClass = getDeclaringClass(); |
| // if ( declaringClass == null ) |
| // throw new IllegalStateException("Missing declaring class"); // NOI18N |
| // |
| // JavaModelPackage jmodel = JavaMetamodel.getManager().getJavaExtent(declaringClass); |
| // Method newMethod = jmodel.getMethod().createMethod(); |
| // int modifiers = Modifier.PUBLIC | Modifier.SYNCHRONIZED; |
| // Parameter newParameter = jmodel.getParameter().createParameter(); |
| // newParameter.setName("listener"); // NOI18N |
| // newParameter.setType(type); |
| // |
| // newMethod.setName( "remove" + capitalizeFirstLetter( getName() ) ); // NOI18N |
| // newMethod.setTypeName(jmodel.getMultipartId().createMultipartId("void", null, null)); // NOI18N |
| // List/*<Parameter>*/ params = newMethod.getParameters(); |
| // params.add(newParameter); |
| // |
| // if ( declaringClass.isInterface() ) { |
| // modifiers &= ~Modifier.SYNCHRONIZED; // synchronized modifier is not allowed in interface |
| // } else if ( body != null ) |
| // newMethod.setBodyText( body ); |
| // newMethod.setModifiers( modifiers ); |
| // if ( javadoc ) { |
| // String comment = MessageFormat.format( PatternNode.getString( "COMMENT_RemoveListenerMethod" ), |
| // new Object[] { ((JavaClass) type).getSimpleName() } ); |
| // newMethod.setJavadocText( comment ); |
| // } |
| // |
| // declaringClass.getContents().add(newMethod); |
| // removeListenerMethod = newMethod; |
| // } |
| // |
| // // Property change support ------------------------------------------------------------------------- |
| // |
| // void copyProperties( EventSetPattern src ) throws JmiException { |
| // assert JMIUtils.isInsideTrans(); |
| // boolean changed = !src.getType().equals( getType() ) || |
| // !src.getName().equals( getName() ) || |
| // !(src.isUnicast() == isUnicast()); |
| // |
| // if ( src.getAddListenerMethod() != addListenerMethod ) |
| // addListenerMethod = src.getAddListenerMethod(); |
| // if ( src.getRemoveListenerMethod() != removeListenerMethod ) |
| // removeListenerMethod = src.getRemoveListenerMethod(); |
| // |
| // if ( changed ) { |
| // |
| // isUnicast = testUnicast(); |
| // |
| // findEventSetType(); |
| // isUnicast = testUnicast(); |
| // name = findEventSetName(); |
| // |
| // // XXX cannot be fired inside mdr transaction; post to dedicated thread or redesigne somehow |
| // firePropertyChange( new java.beans.PropertyChangeEvent( this, null, null, null ) ); |
| // } |
| // |
| // } |
| |
| } |