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.beaninfo;
043:
044: import java.util.ArrayList;
045: import java.util.Collection;
046: import java.util.Comparator;
047: import java.util.Iterator;
048: import java.util.List;
049: import javax.lang.model.element.ExecutableElement;
050: import javax.lang.model.element.TypeElement;
051: import javax.lang.model.element.VariableElement;
052: import javax.lang.model.type.ArrayType;
053: import javax.lang.model.type.DeclaredType;
054: import javax.lang.model.type.TypeKind;
055: import javax.lang.model.type.TypeMirror;
056: import javax.lang.model.util.ElementFilter;
057: import org.netbeans.api.java.source.CompilationInfo;
058: import org.netbeans.api.java.source.ElementHandle;
059: import org.netbeans.api.java.source.ui.ElementHeaders;
060: import org.netbeans.modules.beans.EventSetPattern;
061: import org.netbeans.modules.beans.GenerateBeanException;
062: import org.netbeans.modules.beans.IdxPropertyPattern;
063: import org.netbeans.modules.beans.Pattern;
064: import org.netbeans.modules.beans.PatternAnalyser;
065: import org.netbeans.modules.beans.PropertyPattern;
066: import org.openide.nodes.Node;
067:
068: /** The basic class representing features included in BeanInfo.
069: *
070: * @author Petr Hrebejk
071: */
072: public abstract class BiFeature implements IconBases, Node.Cookie,
073: Comparable {
074:
075: /** generated Serialized Version UID */
076: //static final long serialVersionUID = -8680621542479107034L;
077: // Function names for code generation and reconition
078: private static final String TEXT_EXPERT = "setExpert"; // NOI18N
079: private static final String TEXT_HIDDEN = "setHidden"; // NOI18N
080: private static final String TEXT_PREFERRED = "setPreferred"; // NOI18N
081: private static final String TEXT_DISPLAY_NAME = "setDisplayName"; // NOI18N
082: private static final String TEXT_SHORT_DESCRIPTION = "setShortDescription"; // NOI18N
083:
084: // variables ..........................................................................
085: private String displayName = null;
086: private boolean expert = false;
087: private boolean hidden = false;
088: private String name = null;
089: private boolean preferred = false;
090: private String shortDescription = null;
091: private boolean included = true;
092:
093: private String brackets = "]"; // NOI18N
094: private final BiAnalyser bia;
095:
096: /**
097: * Creates empty BiFeature.
098: */
099: public BiFeature(Pattern pattern, BiAnalyser bia) {
100: this (pattern.getName(), bia);
101: }
102:
103: BiFeature(String name, String displayName, BiAnalyser bia) {
104: this .name = name;
105: this .displayName = displayName;
106: this .bia = bia;
107: }
108:
109: protected BiFeature(BiAnalyser bia) {
110: this ("beanDescriptor", bia);//NOI18N GenerateBeanInfoAction.getString("CTL_NODE_DescriptorDisplayName");
111: }
112:
113: private BiFeature(String name, BiAnalyser bia) {
114: this (name, null, bia);
115: }
116:
117: abstract String getCreationString();
118:
119: protected final void setModified() {
120: bia.setModified();
121: }
122:
123: // Definition of properties ....................................................................
124:
125: public String getDisplayName() {
126: return displayName;
127: }
128:
129: public void setDisplayName(String displayName) {
130: this .displayName = displayName;
131: setModified();
132: }
133:
134: public boolean isExpert() {
135: return expert;
136: }
137:
138: public void setExpert(boolean expert) {
139: this .expert = expert;
140: setModified();
141: }
142:
143: public boolean isHidden() {
144: return hidden;
145: }
146:
147: public void setHidden(boolean hidden) {
148: this .hidden = hidden;
149: setModified();
150: }
151:
152: public String getName() {
153: return name;
154: }
155:
156: public void setName(String name) {
157: this .name = name;
158: }
159:
160: public boolean isPreferred() {
161: return preferred;
162: }
163:
164: public void setPreferred(boolean preferred) {
165: this .preferred = preferred;
166: setModified();
167: }
168:
169: public String getShortDescription() {
170: return shortDescription;
171: }
172:
173: public void setShortDescription(String shortDescription) {
174: this .shortDescription = shortDescription;
175: setModified();
176: }
177:
178: abstract String getBracketedName();
179:
180: String getBrackets() {
181: return brackets;
182: }
183:
184: void setBrackets(String brackets) {
185: this .brackets = brackets;
186: setModified();
187: }
188:
189: public boolean isIncluded() {
190: return included;
191: }
192:
193: public void setIncluded(boolean included) {
194: this .included = included;
195: setModified();
196: }
197:
198: public String getToolTip() {
199: return this .getName();
200: }
201:
202: /** Generates collection of strings which customize the feature */
203: List<String> getCustomizationStrings() {
204: List<String> col = new ArrayList<String>();
205: StringBuffer sb = new StringBuffer(100);
206:
207: if (expert) {
208: sb.setLength(0);
209: sb.append(TEXT_EXPERT).append(" ( true )"); // NOI18N
210: col.add(sb.toString());
211: }
212: if (hidden) {
213: sb.setLength(0);
214: sb.append(TEXT_HIDDEN).append(" ( true )"); // NOI18N
215: col.add(sb.toString());
216: }
217: if (preferred) {
218: sb.setLength(0);
219: sb.append(TEXT_PREFERRED).append(" ( true )"); // NOI18N
220: col.add(sb.toString());
221: }
222: if (displayName != null && displayName.trim().length() > 0) {
223: sb.setLength(0);
224: sb.append(TEXT_DISPLAY_NAME).append(" ( "); // NOI18N
225: sb.append(displayName).append(" )"); // NOI18N
226: col.add(sb.toString());
227: }
228: if (shortDescription != null
229: && shortDescription.trim().length() > 0) {
230: sb.setLength(0);
231: sb.append(TEXT_SHORT_DESCRIPTION).append(" ( "); // NOI18N
232: sb.append(shortDescription).append(" )"); // NOI18N
233: col.add(sb.toString());
234: }
235:
236: return col;
237: }
238:
239: /** Analyzes the bean info code for all customizations */
240: void analyzeCustomization(Collection<String> code)
241: throws GenerateBeanException {
242: setIncluded(false);
243:
244: Iterator<String> it = code.iterator();
245: String n = getBracketedName();
246:
247: String stNew = n + "=new"; // NOI18N
248: String stExpert = n + "." + TEXT_EXPERT; // NOI18N
249: String stHidden = n + "." + TEXT_HIDDEN; // NOI18N
250: String stPreferred = n + "." + TEXT_PREFERRED; // NOI18N
251: String stDisplayName = n + "." + TEXT_DISPLAY_NAME; // NOI18N
252: String stShortDescription = n + "." + TEXT_SHORT_DESCRIPTION; // NOI18N
253: while (it.hasNext()) {
254: String statement = it.next();
255:
256: if (statement.indexOf(stNew) != -1) {
257: setIncluded(true);
258: analyzeCreationString(statement); // Implemented in descendants
259: continue;
260: }
261: if (statement.indexOf(stExpert) != -1) {
262: this .setExpert(true);
263: continue;
264: }
265: if (statement.indexOf(stHidden) != -1) {
266: this .setHidden(true);
267: continue;
268: }
269: if (statement.indexOf(stPreferred) != -1) {
270: this .setPreferred(true);
271: continue;
272: }
273: if (statement.indexOf(stDisplayName) != -1) {
274: String param = BiAnalyser
275: .getArgumentParameter(statement);
276:
277: if (param != null)
278: this .setDisplayName(param);
279: continue;
280: }
281: if (statement.indexOf(stShortDescription) != -1) {
282: String param = BiAnalyser
283: .getArgumentParameter(statement);
284:
285: if (param != null)
286: this .setShortDescription(param);
287: continue;
288: }
289: analyzeCustomizationString(statement); // Implemented in descendants
290: }
291: }
292:
293: /** gets the current icon base for the feature */
294: abstract String getIconBase(boolean defaultIcon);
295:
296: abstract void analyzeCreationString(String statement);
297:
298: abstract void analyzeCustomizationString(String statement);
299:
300: public static final class Descriptor extends BiFeature {
301: ElementHandle<TypeElement> element;
302: String customizer;
303: private String beanName;
304:
305: Descriptor(TypeElement ce, BiAnalyser bia)
306: throws GenerateBeanException {
307: super (bia);
308: this .element = ElementHandle.create(ce);
309: this .beanName = ce.getQualifiedName().toString();
310: }
311:
312: /** Returns the call to constructor of PropertyDescriptor */
313: String getCreationString() {
314: StringBuilder sb = new StringBuilder(100);
315:
316: sb.append("new BeanDescriptor ( "); // NOI18N
317: sb.append(getBeanName() + ".class , "); // NOI18N
318: sb.append(String.valueOf(getCustomizer()) + " )"); // NOI18N
319:
320: return sb.toString();
321: }
322:
323: String getIconBase(boolean defaultIcon) {
324: //now there be no icon !!!
325: //if( defaultIcon )
326: // return null;
327: //else
328: // return null; // NOI18N
329: return BIF_DESCRIPTOR; // NOI18N
330: }
331:
332: void analyzeCustomizationString(String statement) {
333: }
334:
335: void analyzeCreationString(String statement) {
336: int beg = statement.indexOf(',');
337: int end = statement.lastIndexOf(')');
338:
339: if (beg != -1 && end != -1 && (++beg < end))
340: setCustomizer(statement.substring(beg, end));
341: else
342: setCustomizer(null);
343: }
344:
345: String getBracketedName() {
346: return getName();
347: }
348:
349: @Override
350: String getBrackets() {
351: return ""; // NOI18N
352: }
353:
354: public String getCustomizer() {
355: return customizer;
356: }
357:
358: public void setCustomizer(String customizer) {
359: this .customizer = customizer;
360: setModified();
361: }
362:
363: //overrides BiFeature.isIncluded(), this property is always included ( disabled by setting get from Introspection )
364: @Override
365: public boolean isIncluded() {
366: return true;
367: }
368:
369: public String getBeanName() {
370: return this .beanName;
371: }
372: }
373:
374: public static class Property extends BiFeature {
375:
376: private PropertyPattern pattern;
377:
378: private static final String TEXT_BOUND = "setBound"; // NOI18N
379: private static final String TEXT_CONSTRAINED = "setConstrained"; // NOI18N
380: private static final String TEXT_PROPERTY_EDITOR = "setPropertyEditorClass"; // NOI18N
381:
382: private boolean bound;
383: private boolean constrained;
384: private int mode;
385: private String propertyEditorClass;
386:
387: private String declaringClassName;
388: private String getterName;
389: private String setterName;
390:
391: Property(PropertyPattern pp, CompilationInfo javac,
392: BiAnalyser bia) throws GenerateBeanException {
393: super (pp, bia);
394: mode = pp.getMode();
395: pattern = pp;
396:
397: TypeElement declaringClass = pattern.getDeclaringClass()
398: .resolve(javac);
399: declaringClassName = declaringClass.getQualifiedName()
400: .toString();
401: ElementHandle<ExecutableElement> getterHandle = pattern
402: .getGetterMethod();
403: getterName = getterHandle == null ? null : getterHandle
404: .resolve(javac).getSimpleName().toString();
405: ElementHandle<ExecutableElement> setterHandle = pattern
406: .getSetterMethod();
407: setterName = setterHandle == null ? null : setterHandle
408: .resolve(javac).getSimpleName().toString();
409: }
410:
411: protected final String getDeclaringClassName() {
412: return declaringClassName;
413: }
414:
415: protected final String getGetterName() {
416: return getterName;
417: }
418:
419: protected final String getSetterName() {
420: return setterName;
421: }
422:
423: public boolean isBound() {
424: return bound;
425: }
426:
427: String getBracketedName() {
428: return "[PROPERTY_" + getName() + "]"; // NOI18N
429: }
430:
431: public void setBound(boolean bound) {
432: this .bound = bound;
433: setModified();
434: }
435:
436: public boolean isConstrained() {
437: return constrained;
438: }
439:
440: public void setConstrained(boolean constrained) {
441: this .constrained = constrained;
442: setModified();
443: }
444:
445: public int getMode() {
446: return mode;
447: }
448:
449: public void setMode(int mode) {
450: this .mode = mode;
451: setModified();
452: }
453:
454: public boolean modeChangeable() {
455: return pattern.getMode() == PropertyPattern.READ_WRITE;
456: }
457:
458: public String getPropertyEditorClass() {
459: return propertyEditorClass;
460: }
461:
462: public void setPropertyEditorClass(String propertyEditorClass) {
463: this .propertyEditorClass = propertyEditorClass;
464: setModified();
465: }
466:
467: /** Returns the call to constructor of PropertyDescriptor */
468: String getCreationString() {
469: StringBuilder sb = new StringBuilder(100);
470:
471: sb.append("new PropertyDescriptor ( "); // NOI18N
472: sb.append("\"" + this .getName() + "\", "); // NOI18N
473: sb.append(declaringClassName + ".class, "); // NOI18N
474:
475: if (getterName != null
476: && getMode() != PropertyPattern.WRITE_ONLY)
477: sb.append("\"" + getterName + "\", "); // NOI18N
478: else
479: sb.append("null, "); // NOI18N
480:
481: if (setterName != null
482: && getMode() != PropertyPattern.READ_ONLY)
483: sb.append("\"" + setterName + "\" )"); // NOI18N
484: else
485: sb.append("null )"); // NOI18N
486:
487: return sb.toString();
488: }
489:
490: String getIconBase(boolean defaultIcon) {
491: if (defaultIcon) {
492: return BIF_PROPERTY_RW + "S"; // NOI18N
493: } else {
494: if (mode == PropertyPattern.READ_ONLY)
495: return BIF_PROPERTY_RO
496: + (this .isIncluded() ? "S" : "N"); // NOI18N
497: else if (mode == PropertyPattern.WRITE_ONLY)
498: return BIF_PROPERTY_WO
499: + (this .isIncluded() ? "S" : "N"); // NOI18N
500: else
501: return BIF_PROPERTY_RW
502: + (this .isIncluded() ? "S" : "N"); // NOI18N
503: }
504: }
505:
506: @Override
507: List<String> getCustomizationStrings() {
508: List<String> col = super .getCustomizationStrings();
509: StringBuilder sb = new StringBuilder(100);
510:
511: if (bound) {
512: sb.setLength(0);
513: sb.append(TEXT_BOUND).append(" ( true )"); // NOI18N
514: col.add(sb.toString());
515: }
516: if (constrained) {
517: sb.setLength(0);
518: sb.append(TEXT_CONSTRAINED).append(" ( true )"); // NOI18N
519: col.add(sb.toString());
520: }
521: if (propertyEditorClass != null
522: && propertyEditorClass.trim().length() > 0) {
523: sb.setLength(0);
524: sb.append(TEXT_PROPERTY_EDITOR).append(" ( "); // NOI18N
525: sb.append(propertyEditorClass).append(" )"); // NOI18N
526: col.add(sb.toString());
527: }
528:
529: return col;
530: }
531:
532: void analyzeCustomizationString(String statement) {
533: String n = getBracketedName();
534: String stBound = n + "." + TEXT_BOUND; // NOI18N
535: String stConstrained = n + "." + TEXT_CONSTRAINED; // NOI18N
536: String stPropertyEditor = n + "." + TEXT_PROPERTY_EDITOR; // NOI18N
537: int peIndex;
538:
539: if (statement.indexOf(stBound) != -1) {
540: setBound(true);
541: return;
542: }
543:
544: if (statement.indexOf(stConstrained) != -1) {
545: setConstrained(true);
546: return;
547: }
548:
549: peIndex = statement.indexOf(stPropertyEditor);
550: if (peIndex != -1) {
551: String paramString = statement.substring(peIndex
552: + stPropertyEditor.length());
553: String[] params = BiAnalyser.getParameters(paramString);
554: if (params.length > 0)
555: setPropertyEditorClass(params[0]);
556: return;
557: }
558: }
559:
560: void analyzeCreationString(String statement) {
561:
562: String[] params = BiAnalyser.getParameters(statement);
563:
564: // Analyses if there is mode restriction in the existing BeanInfo
565: if (params.length == 4
566: && mode == PropertyPattern.READ_WRITE) {
567: if (params[2].equals("null")) // NOI18N
568: mode = PropertyPattern.WRITE_ONLY;
569: else if (params[3].equals("null")) // NOI18N
570: mode = PropertyPattern.READ_ONLY;
571: }
572: }
573: }
574:
575: public static final class IdxProperty extends Property {
576:
577: private boolean niGetter;
578: private boolean niSetter;
579:
580: IdxPropertyPattern pattern;
581: private String indexedGetterName;
582: private String indexedSetterName;
583:
584: IdxProperty(IdxPropertyPattern pp, CompilationInfo javac,
585: BiAnalyser bia) throws GenerateBeanException {
586: super (pp, javac, bia);
587: pattern = pp;
588:
589: niGetter = hasNiGetter();
590: niSetter = hasNiSetter();
591: ElementHandle<ExecutableElement> indexedGetterHandle = pattern
592: .getIndexedGetterMethod();
593: indexedGetterName = indexedGetterHandle == null ? null
594: : indexedGetterHandle.resolve(javac)
595: .getSimpleName().toString();
596: ElementHandle<ExecutableElement> indexedSetterHandle = pattern
597: .getIndexedSetterMethod();
598: indexedSetterName = indexedSetterHandle == null ? null
599: : indexedSetterHandle.resolve(javac)
600: .getSimpleName().toString();
601: }
602:
603: boolean isNiGetter() {
604: return niGetter;
605: }
606:
607: void setNiGetter(boolean niGetter) {
608: this .niGetter = hasNiGetter() ? niGetter : false;
609: setModified();
610: }
611:
612: boolean isNiSetter() {
613: return niSetter;
614: }
615:
616: void setNiSetter(boolean niSetter) {
617: this .niGetter = hasNiSetter() ? niSetter : false;
618: setModified();
619: }
620:
621: boolean hasNiGetter() {
622: return pattern.getGetterMethod() != null;
623: }
624:
625: boolean hasNiSetter() {
626: return pattern.getGetterMethod() != null;
627: }
628:
629: /** Returns the call to constructor of IndexedPropertyDescriptor */
630: @Override
631: String getCreationString() {
632: StringBuffer sb = new StringBuffer(100);
633:
634: sb.append("new IndexedPropertyDescriptor ( "); // NOI18N
635: sb.append("\"" + this .getName() + "\", "); // NOI18N
636: sb.append(getDeclaringClassName() + ".class, "); // NOI18N
637:
638: if (getGetterName() != null && niGetter)
639: sb.append("\"" + getGetterName() + "\", "); // NOI18N
640: else
641: sb.append("null, "); // NOI18N
642:
643: if (getSetterName() != null && niSetter)
644: sb.append("\"" + getSetterName() + "\", "); // NOI18N
645: else
646: sb.append("null, "); // NOI18N
647:
648: if (indexedGetterName != null
649: && getMode() != PropertyPattern.WRITE_ONLY)
650: sb.append("\"" + indexedGetterName + "\", "); // NOI18N
651: else
652: sb.append("null, "); // NOI18N
653:
654: if (indexedSetterName != null
655: && getMode() != PropertyPattern.READ_ONLY)
656: sb.append("\"" + indexedSetterName + "\" )"); // NOI18N
657: else
658: sb.append("null )"); // NOI18N
659:
660: return sb.toString();
661: }
662:
663: @Override
664: String getIconBase(boolean defaultIcon) {
665: if (defaultIcon) {
666: return BIF_IDXPROPERTY_RW + "S"; // NOI18N
667: } else {
668: if (getMode() == PropertyPattern.READ_ONLY)
669: return BIF_IDXPROPERTY_RO
670: + (this .isIncluded() ? "S" : "N"); // NOI18N
671: else if (getMode() == PropertyPattern.WRITE_ONLY)
672: return BIF_IDXPROPERTY_WO
673: + (this .isIncluded() ? "S" : "N"); // NOI18N
674: else
675: return BIF_IDXPROPERTY_RW
676: + (this .isIncluded() ? "S" : "N"); // NOI18N
677: }
678: }
679:
680: @Override
681: void analyzeCreationString(String statement) {
682: String[] params = BiAnalyser.getParameters(statement);
683:
684: // Analyses if there is mode restriction in the existing BeanInfo
685: if (params.length == 6
686: && getMode() == PropertyPattern.READ_WRITE) {
687: if (params[4].equals("null")) // NOI18N
688: setMode(PropertyPattern.WRITE_ONLY);
689: else if (params[5].equals("null")) // NOI18N
690: setMode(PropertyPattern.READ_ONLY);
691:
692: // Analayses if there is restriction on non indexed getter or setter
693: if (hasNiGetter() && params[2].equals(null))
694: niGetter = false;
695: if (hasNiGetter() && params[3].equals(null))
696: niSetter = false;
697:
698: }
699: }
700:
701: }
702:
703: public static final class EventSet extends BiFeature implements
704: Comparator {
705:
706: EventSetPattern pattern;
707:
708: private static final String TEXT_UNICAST = "setUnicast"; // NOI18N
709: private static final String TEXT_IN_DEFAULT = "setInDefaultEventSet"; // NOI18N
710:
711: private boolean isInDefaultEventSet = true;
712: private String creationString;
713:
714: EventSet(EventSetPattern esp, CompilationInfo javac,
715: BiAnalyser bia) throws GenerateBeanException {
716: super (esp, bia);
717: pattern = esp;
718: creationString = initCreationString(javac);
719: }
720:
721: public boolean isUnicast() {
722: return pattern.isUnicast();
723: }
724:
725: public boolean isInDefaultEventSet() {
726: return isInDefaultEventSet;
727: }
728:
729: public void setInDefaultEventSet(boolean isInDefaultEventSet) {
730: this .isInDefaultEventSet = isInDefaultEventSet;
731: }
732:
733: /**
734: * MUST be consistent w/ generator in BiAnalyser.
735: * @return
736: */
737: String getBracketedName() {
738: return "[EVENT_" + getName() + "]"; // NOI18N
739: }
740:
741: public int compare(Object o1, Object o2) {
742: // XXX was used to sort listener methods in initCreationString
743: throw new UnsupportedOperationException();
744: // if (!(o1 instanceof org.netbeans.jmi.javamodel.Method) ||
745: // !(o2 instanceof org.netbeans.jmi.javamodel.Method))
746: // throw new IllegalArgumentException();
747: // org.netbeans.jmi.javamodel.Method m1 = (org.netbeans.jmi.javamodel.Method) o1;
748: // org.netbeans.jmi.javamodel.Method m2 = (org.netbeans.jmi.javamodel.Method) o2;
749: //
750: // return m1.getName().compareTo(m2.getName());
751: }
752:
753: /** Returns the call to constructor of EventSetDescriptor */
754: String getCreationString() {
755: return creationString;
756: }
757:
758: private String initCreationString(CompilationInfo javac)
759: throws GenerateBeanException {
760: String code = "new EventSetDescriptor ( %1$s.class, \"%2$s\", %3$s.class, new String[] {%4$s}, \"%5$s\", \"%6$s\" )"; // NOI18N
761: String paramdelim = ", "; //NOI18N
762: StringBuilder methodList = new StringBuilder();
763: TypeMirror listenerType = pattern.getType().resolve(javac);
764: TypeElement listener = (TypeElement) ((DeclaredType) listenerType)
765: .asElement();
766: // is sorting necessary here?
767: for (ExecutableElement me : ElementFilter
768: .methodsIn(listener.getEnclosedElements())) {
769: methodList.append(paramdelim).append('"').append(
770: me.getSimpleName()).append('"');
771: }
772:
773: return String.format(code, pattern.getDeclaringClass()
774: .resolve(javac).getQualifiedName(), pattern
775: .getName(), pattern.getType().resolve(javac)
776: .toString(), // XXX ???
777: methodList.length() == 0 ? methodList : methodList
778: .substring(paramdelim.length()), pattern
779: .getAddListenerMethod().resolve(javac)
780: .getSimpleName(), pattern
781: .getRemoveListenerMethod().resolve(javac)
782: .getSimpleName());
783: }
784:
785: String getIconBase(boolean defaultIcon) {
786: if (defaultIcon) {
787: if (isUnicast())
788: return BIF_EVENTSET_UNICAST + "S"; // NOI18N
789: else
790: return BIF_EVENTSET_MULTICAST + "S"; // NOI18N
791: } else {
792: if (isUnicast())
793: return BIF_EVENTSET_UNICAST
794: + (this .isIncluded() ? "S" : "N"); // NOI18N
795: else
796: return BIF_EVENTSET_MULTICAST
797: + (this .isIncluded() ? "S" : "N"); // NOI18N
798: }
799: }
800:
801: @Override
802: List<String> getCustomizationStrings() {
803: List<String> col = super .getCustomizationStrings();
804: StringBuilder sb = new StringBuilder(100);
805:
806: if (isUnicast()) {
807: sb.setLength(0);
808: sb.append(TEXT_UNICAST).append(" ( true )"); // NOI18N
809: col.add(sb.toString());
810: }
811: if (!isInDefaultEventSet) {
812: sb.setLength(0);
813: sb.append(TEXT_IN_DEFAULT).append(" ( false )"); // NOI18N
814: col.add(sb.toString());
815: }
816:
817: return col;
818: }
819:
820: void analyzeCustomizationString(String statement) {
821: String n = getBracketedName();
822: // String stUnicast = new String( n + "." + TEXT_UNICAST ); // NOI18N
823: String stInDefault = n + "." + TEXT_IN_DEFAULT; // NOI18N
824: /*
825: if ( statement.indexOf( stUnicast ) != -1 ) {
826: setUnicast( true );
827: return;
828: }
829: */
830: if (statement.indexOf(stInDefault) != -1) {
831: setInDefaultEventSet(false);
832: return;
833: }
834: }
835:
836: void analyzeCreationString(String statement) {
837: }
838:
839: }
840:
841: public static final class Method extends BiFeature {
842: private ElementHandle<ExecutableElement> element;
843: private String varName;
844: private String toolTip;
845: private String creationString;
846:
847: Method(ExecutableElement me, PatternAnalyser pa,
848: CompilationInfo javac, BiAnalyser bia)
849: throws GenerateBeanException {
850: super (me.getSimpleName().toString(), "\"\"", bia); //NOI18N
851: element = ElementHandle.create(me);
852: toolTip = initToolTip(me, javac);
853: creationString = initCreationString(me);
854: }
855:
856: String getBracketedName() {
857: return "[METHOD_" + getName() + "]"; // NOI18N
858: }
859:
860: private static String getTypeClass(TypeMirror type) {
861: TypeKind kind = type.getKind();
862: if (kind.isPrimitive()) {
863: return kind.name();
864: } else if (kind == TypeKind.ARRAY) {
865: return resolveArrayClass((ArrayType) type);
866: } else if (kind == TypeKind.DECLARED) {
867: return ((TypeElement) ((DeclaredType) type).asElement())
868: .getQualifiedName().toString();
869: } else {
870: throw new IllegalStateException("Unknown type" + type); // NOI18N
871: }
872: }
873:
874: private static String resolveArrayClass(ArrayType array) {
875: TypeMirror type = array;
876: StringBuilder dim = new StringBuilder();
877: for (int i = 0; type.getKind() == TypeKind.ARRAY; i++) {
878: type = ((ArrayType) type).getComponentType();
879: dim.append("[]"); // NOI18N
880: }
881:
882: return getTypeClass(type) + dim;
883: }
884:
885: @Override
886: public String getToolTip() {
887: return this .toolTip;
888: }
889:
890: private static String initToolTip(ExecutableElement element,
891: CompilationInfo javac) {
892: return ElementHeaders.getHeader(element, javac,
893: ElementHeaders.NAME + ElementHeaders.PARAMETERS);
894: }
895:
896: ElementHandle<ExecutableElement> getElement() {
897: return element;
898: }
899:
900: // Returns the call to constructor of MethodDescriptor
901: String getCreationString() {
902: return creationString;
903: }
904:
905: private static String initCreationString(
906: ExecutableElement element) {
907: TypeElement enclClass = (TypeElement) element
908: .getEnclosingElement();
909: String code = "new MethodDescriptor(%1$s.class.getMethod(\"%2$s\", new Class[] {%3$s}))"; // NOI18N
910: String paramdelim = ", "; //NOI18N
911: StringBuilder sb = new StringBuilder();
912: for (VariableElement param : element.getParameters()) {
913: sb.append(paramdelim).append(
914: getTypeClass(param.asType())).append(".class"); // NOI18N
915: }
916:
917: return String.format(code, enclClass.getQualifiedName(),
918: element.getSimpleName(), sb.length() == 0 ? sb : sb
919: .substring(paramdelim.length()));
920: }
921:
922: String getIconBase(boolean defaultIcon) {
923: if (defaultIcon)
924: return BIF_METHOD + "S"; // NOI18N
925: else
926: return BIF_METHOD + (this .isIncluded() ? "S" : "N"); // NOI18N
927: }
928:
929: void analyzeCustomizationString(String statement) {
930: }
931:
932: void analyzeCreationString(String statement) {
933: }
934:
935: /** Analyzes the bean info code for all customizations */
936: @Override
937: void analyzeCustomization(Collection<String> code)
938: throws GenerateBeanException {
939: if (element != null) {
940: // find the method identifier
941: String creation = (String) BiAnalyser.normalizeText(
942: this .getCreationString()).toArray()[0];
943: Iterator<String> it = code.iterator();
944: int index;
945:
946: while (it.hasNext()) {
947: String statement = (String) it.next();
948: if ((index = statement.indexOf(creation)) > -1) {
949: this .varName = statement.substring(statement
950: .indexOf("methods[METHOD_") + 15,
951: index - 2); // NOI18N
952: break;
953: }
954: }
955:
956: element = null;
957: }
958:
959: String realName = this .getName();
960: this .setName(varName);
961: super .analyzeCustomization(code);
962: this .setName(realName);
963: }
964:
965: }
966:
967: public int compareTo(Object other) {
968: if (!(other instanceof BiFeature))
969: return -1;
970: BiFeature bf = (BiFeature) other;
971: return getName().compareToIgnoreCase(bf.getName());
972: }
973: }
|