KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > rtti > NamingConventions


1 /*
2   Copyright (C) 2001-2002 Renaud Pawlak <renaud@aopsys.com>
3   Laurent Martelli <laurent@aopsys.com>
4   
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU Lesser General Public License as
7   published by the Free Software Foundation; either version 2 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   GNU Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

18
19 package org.objectweb.jac.core.rtti;
20
21 import java.lang.reflect.*;
22 import java.util.*;
23
24 /**
25  * This class provides some useful methods to get some information
26  * regarding the naming conventions.
27  *
28  * @author Renaud Pawlak
29  * @author Laurent Martelli
30  */

31
32 public class NamingConventions {
33
34    /** Constant to represent field modifiers. */
35    public static final int MODIFIER = 0;
36
37    /** Constant to represent field getters. */
38    public static final int GETTER = 1;
39
40    /** Constant to represent field setters. */
41    public static final int SETTER = 2;
42
43    /** Constant to represent collection adders. */
44    public static final int ADDER = 3;
45
46    /** Constant to represent collection removers. */
47    public static final int REMOVER = 4;
48
49    /** Store default field getter prefixes (get...). */
50    public static final String JavaDoc[] getterPrefixes;
51
52    /** Store default field setter prefixes (set...). */
53    public static final String JavaDoc[] setterPrefixes;
54
55    /** Store default collection adder prefixes (add..., put...). */
56    public static final String JavaDoc[] adderPrefixes;
57
58    /** Store default collection remover prefixes (rmv..., del...,
59        remove...). */

60    public static final String JavaDoc[] removerPrefixes;
61
62    static {
63       getterPrefixes = new String JavaDoc[] { "get", "is" };
64       setterPrefixes = new String JavaDoc[] { "set" };
65       adderPrefixes = new String JavaDoc[] { "add","put" };
66       removerPrefixes = new String JavaDoc[] { "rmv", "del", "remove", "clear" };
67    }
68
69    /**
70     * Returns the short name of a class.
71     *
72     * <p>If it is a well-known java class or a well-known JAC class,
73     * truncates the packages to give only the class name. It is is an
74     * array, add [] after the primitive type.
75     *
76     * @param cli the class item
77     */

78    public static String JavaDoc getShortClassName(ClassItem cli) {
79       return getShortClassName(cli.getActualClass());
80    }
81
82    /**
83     * Returns the short name of a class.
84     *
85     * <p>If it is a well-known java class or a well-known JAC class,
86     * truncates the packages to give only the class name. It is is an
87     * array, add [] after the primitive type.
88     *
89     * @param cl the class
90     */

91    public static String JavaDoc getShortClassName(Class JavaDoc cl) {
92
93       String JavaDoc type = cl.getName();
94
95       if (cl.isArray()) {
96          type = cl.getComponentType().getName();
97       }
98
99       if (type.startsWith("java") || type.startsWith( "org.objectweb.jac")) {
100          type = type.substring(type.lastIndexOf( '.' )+1);
101       }
102
103       if (cl.isArray()) {
104          type = type + "[]";
105       }
106
107       return type;
108       
109    }
110
111    public static String JavaDoc getStandardClassName(Class JavaDoc cl) {
112       String JavaDoc type = cl.getName();
113       if ( cl.isArray() ) {
114          type = cl.getComponentType().getName()+"[]";
115       }
116       return type;
117    }
118
119    /**
120     * Returns the short name of a given constructor.
121     *
122     * <p>By default, the name of a constructor contains the full path
123     * name of the constructor class. Thus, this method is equivalent
124     * to get the short name of the constructor class.
125     *
126     * @param constructor a constructor
127     * @return its short name
128     * @see #getShortClassName(Class) */

129
130    public static String JavaDoc getShortConstructorName(Constructor constructor) {
131       String JavaDoc name = constructor.getName();
132       if ( name.lastIndexOf( '.' ) == -1 ) {
133          return name;
134       }
135       return name.substring(name.lastIndexOf( '.' ) + 1);
136    }
137
138    /**
139     * Returns the short name of a given constructor.
140     *
141     * <p>By default, the name of a constructor contains the full path
142     * name of the constructor class. Thus, this method is equivalent
143     * to get the short name of the constructor class.
144     *
145     * @param constructor a constructor
146     * @return its short name
147     * @see #getShortClassName(ClassItem) */

148
149    public static String JavaDoc getShortConstructorName(ConstructorItem constructor) {
150       return getShortConstructorName(constructor.getActualConstructor());
151    }
152
153    /**
154     * Returns the package name of the given class.
155     *
156     * @param cl the class to get the package of
157     * @return the name of the package where <code>cl</code> is defined
158     */

159
160    public static String JavaDoc getPackageName(Class JavaDoc cl) {
161       String JavaDoc type = cl.getName();
162
163       return type.substring(0,type.lastIndexOf("."));
164    }
165
166    /**
167     * Returns a printable representation of the argument types of a
168     * method (or a constructor if needed).
169     *
170     * <p>For instance, for a method that takes one object, one string,
171     * and one string array, the result will look like "Object, String,
172     * String[]".
173     *
174     * @param method the involved method
175     * @return a printable string
176     * @see #getPrintableParameterTypes(AbstractMethodItem) */

177
178    public static String JavaDoc getPrintableParameterTypes(AccessibleObject method) {
179       String JavaDoc ret = "(";
180       
181       Class JavaDoc[] pts;
182       if ( method instanceof Constructor )
183          pts = ((Constructor)method).getParameterTypes();
184       else if ( method instanceof Method )
185          pts = ((Method)method).getParameterTypes();
186       else return "";
187       for ( int j = 0; j < pts.length; j++ ) {
188          ret = ret + getShortClassName( pts[j] );
189          if ( j < pts.length - 1 ) ret = ret + ",";
190       }
191       ret = ret + ")";
192       return ret;
193    }
194
195    /**
196     * Returns a printable representation of the argument types of a
197     * method (or a constructor if needed).
198     *
199     * <p>Same as its homonym but uing RTTI meta item.
200     *
201     * @param method the involved method
202     * @return a printable string
203     * @see #getPrintableParameterTypes(AccessibleObject) */

204
205    public static String JavaDoc getPrintableParameterTypes(AbstractMethodItem method) {
206       String JavaDoc ret = "(";
207       
208       Class JavaDoc[] pts = method.getParameterTypes();
209       for ( int j = 0; j < pts.length; j++ ) {
210          ret = ret + getShortClassName( pts[j] );
211          if ( j < pts.length - 1 ) ret = ret + ",";
212       }
213       ret = ret + ")";
214       return ret;
215    }
216
217    /**
218     * Returns a declared method of a class <code>c</code> only by
219     * knowing its name. Returns null if not found (to be modified to
220     * raise an exception.
221     *
222     * @param c the class.
223     * @param name the name of the method to find.
224     * @return the method (null if not found). */

225
226    public static Method getDeclaredMethodByName(Class JavaDoc c, String JavaDoc name) {
227
228       Method[] methods = c.getDeclaredMethods();
229
230       for ( int i=0 ; i < methods.length ; i++) {
231          if ( name.equals(methods[i].getName()) ) {
232             return methods[i];
233          }
234       }
235
236       return null;
237    }
238
239    /**
240     * Tell if the string is prefixed with one of the given prefixes.
241     *
242     * <p>Returns 0 if the candidate is not prefixed by any of the
243     * given prefixes and also if the candidate exactly equals one of
244     * the prefixes.
245     *
246     * @param candidate the string to test
247     * @param prefixes the tested prefixes
248     *
249     * @return the length of the matching prefix, 0 if not prefixed */

250
251    public static int isPrefixedWith(String JavaDoc candidate, String JavaDoc[] prefixes) {
252       for ( int i = 0; i < prefixes.length; i++ ) {
253          if ( prefixes[i].equals(candidate) )
254             return 0;
255          if ( candidate.startsWith(prefixes[i]) )
256             return prefixes[i].length();
257       }
258       return 0;
259    }
260
261    /**
262     * Tells if the the method name is equal to one of the given
263     * prefixes.
264     *
265     * @return true if equals */

266
267    public static boolean isInPrefixes(String JavaDoc candidate, String JavaDoc[] prefixes) {
268       for ( int i = 0; i < prefixes.length; i++ ) {
269          if ( prefixes[i].equals(candidate) ) return true;
270       }
271       return false;
272    }
273
274    /**
275     * Return true if the name matches a setter profile (i.e. set...).
276     *
277     * @param name the string to test
278     * @return true if setter profile
279     */

280
281    public static boolean isSetter(String JavaDoc name) {
282       return isPrefixedWith(name, setterPrefixes) != 0 ;
283    }
284
285    /**
286     * Return true if the name matches a getter profile (i.e. get...).
287     *
288     * @param name the string to test
289     * @return true if getter profile */

290
291    public static boolean isGetter(String JavaDoc name) {
292       return isPrefixedWith(name, getterPrefixes) != 0 ;
293    }
294
295    /**
296     * Return true if the name matches a adder profile (i.e. add...).
297     *
298     * @param name the string to test
299     * @return true if adder profile */

300
301    public static boolean isAdder(String JavaDoc name) {
302       return isPrefixedWith(name, adderPrefixes) != 0 ;
303    }
304
305    /**
306     * Return true if the name matches a remover profile (i.e. rmv...,
307     * del..., remove...).
308     *
309     * @param name the string to test
310     * @return true if remover profile */

311
312    public static boolean isRemover(String JavaDoc name) {
313       return isPrefixedWith( name, removerPrefixes ) != 0 ;
314    }
315
316    /**
317     * Returns true if the name matches a modifier profile
318     * (i.e. setter, adder, or remover profile).
319     *
320     * @param name the string to test
321     * @return true if modifier profile */

322
323    public static boolean isModifier(String JavaDoc name) {
324       return isSetter(name) || isAdder(name) || isRemover(name) ||
325          isInPrefixes(name, removerPrefixes) || isInPrefixes(name, adderPrefixes);
326    }
327
328    /**
329     * Takes a string and returns a new capitalized one.
330     *
331     * @param str the original string
332     * @return a new capitalized version of <code>str</code> */

333    
334    public static String JavaDoc capitalize(String JavaDoc str) {
335       if ( str.length() == 0 )
336          return str;
337       StringBuffer JavaDoc sb = new StringBuffer JavaDoc(str);
338       sb.setCharAt(0, Character.toUpperCase(str.charAt(0)) );
339       return sb.toString();
340    }
341
342    /**
343     * Returns the normalized name for a string.
344     *
345     * <p>A normalized string is a blank-free word where each relevant
346     * substring starts with an upcase character.<br>
347     *
348     * <p>For instance:
349     *
350     * <ul><pre>
351     * - one string --> OneString
352     * - one_string --> OneString
353     * - oneString --> OneString
354     * - one.s-tring --> OneSTring
355     * </pre></ul>
356     *
357     * @param string the string to normalize
358     * @return the normalized string */

359
360    public static String JavaDoc getNormalizedString(String JavaDoc string) {
361       if ( string.length() == 0 ) return string;
362       StringBuffer JavaDoc sb = new StringBuffer JavaDoc( string.length() );
363       sb.append ( Character.toUpperCase( string.charAt( 0 ) ) );
364       boolean wordSep = false;
365       for ( int i = 1; i < string.length(); i++ ) {
366          char c = string.charAt( i );
367          if ( c == '_' || c == '.' || c == ' ' || c == '-' ) {
368             wordSep = true;
369          } else {
370             if ( wordSep ) {
371                wordSep = false;
372                sb.append ( Character.toUpperCase( c ) );
373             } else {
374                sb.append ( c );
375             }
376          }
377       }
378       return new String JavaDoc( sb );
379    }
380
381    /**
382     * Returns the underscored name for a normalized string.
383     *
384     * <p>A normalized string is a blank-free word where each relevant
385     * substring starts with an upcase character.<br>
386     *
387     * <p>For instance:
388     *
389     * <ul><pre>
390     * - OneString --> one_string
391     * </pre></ul>
392     *
393     * @param string a normalized string
394     * @return the underscored string
395     */

396
397    public static String JavaDoc getUnderscoredString(String JavaDoc string) {
398       if (string.length() == 0)
399          return string;
400       StringBuffer JavaDoc sb = new StringBuffer JavaDoc(string.length());
401       sb.append(Character.toLowerCase(string.charAt(0)));
402       for (int i=1; i<string.length(); i++) {
403          char c = string.charAt(i);
404          if (Character.isUpperCase(c)) {
405             sb.append('_');
406             sb.append(Character.toLowerCase(c));
407          } else {
408             sb.append(c);
409          }
410       }
411       return new String JavaDoc(sb);
412    }
413
414    /**
415     * Lower case the first character of a string.
416     *
417     * @param string the string to transform
418     * @return the same string but with the first character lowered
419     */

420    public static String JavaDoc lowerFirst(String JavaDoc string) {
421       if (string.equals(""))
422          return string;
423       char[] chs = string.toCharArray();
424       chs[0] = Character.toLowerCase(chs[0]);
425       return String.copyValueOf(chs);
426    }
427
428    /**
429     * Lower case the first character of a string unless it starts with
430     * at least two upper case letters.
431     *
432     * @param string the string to transform
433     * @return the same string but with the first character lowered */

434    public static String JavaDoc maybeLowerFirst(String JavaDoc string) {
435       if (!(string.length()>1 &&
436             Character.isUpperCase(string.charAt(0)) &&
437             Character.isUpperCase(string.charAt(1))))
438          return lowerFirst(string);
439       else
440          return string;
441    }
442
443    /**
444     * Get an unprefixed string from a prefixed string.<br>
445     *
446     * <p><b>NOTE:</b> this method is not semantically indentical to
447     * <code>removePrefixFrom</code>.
448     *
449     * <p>For instance:
450     *
451     * <ul><pre>
452     * - getName --> Name
453     * - addName --> Names
454     * - removeName --> Names
455     * </pre></ul>
456     *
457     * @param string a prefixed string
458     * @return the corresponding unprefixed string
459     * @see #removePrefixFrom(String) */

460
461    public static String JavaDoc getUnprefixedString(String JavaDoc string) {
462       String JavaDoc ret = string;
463       int ps = 0; /* prefix size */
464       
465       if( (ps = isPrefixedWith( string, removerPrefixes )) != 0 ) {
466          ret = getPlural(string.substring(ps));
467       } else if( (ps = isPrefixedWith( string, adderPrefixes )) != 0 ) {
468          ret = getPlural(string.substring(ps));
469       } else if( (ps = isPrefixedWith( string, setterPrefixes )) != 0 ) {
470          ret = string.substring(ps);
471       } else if( (ps = isPrefixedWith( string, getterPrefixes )) != 0 ) {
472          ret = string.substring(ps);
473       }
474
475       return ret;
476    }
477
478    /**
479     * Returns the plural of a name
480     *
481     * <p></p>
482     *
483     * @param name the name
484     * @return the plural of name
485     */

486    public static String JavaDoc getPlural(String JavaDoc name) {
487       if (!name.endsWith("s")) {
488          if (name.endsWith("y")) {
489             return name.substring( 0, name.length()-1 )+"ie";
490          } else {
491             return name + "s";
492          }
493       } else {
494          return name + "es";
495       }
496    }
497
498    /**
499     * Return the singular of a name. Handles english -ies plurals,
500     * and -s. If no plural is recognized, returns name.
501     */

502    public static String JavaDoc getSingular(String JavaDoc name) {
503       if (name.endsWith("ies")) {
504          return name.substring(0, name.length()-3)+"y";
505       } else if (name.endsWith("s")) {
506          return name.substring(0, name.length()-1);
507       } else {
508          return name;
509       }
510    }
511
512    /**
513     * Removes the prefix from a prefixed string.
514     *
515     * <p><b>NOTE:</b> this method is not semantically indentical to
516     * <code>getUnprefixedString</code>.
517     *
518     * <p>For instance:
519     *
520     * <ul><pre>
521     * - getName --> Name
522     * - addName --> Name
523     * - removeName --> Name
524     * </pre></ul>
525     *
526     * @param string a prefixed string
527     * @return the corresponding unprefixed string
528     * @see #getUnprefixedString(String) */

529
530    public static String JavaDoc removePrefixFrom(String JavaDoc string) {
531       String JavaDoc ret = string;
532       int ps = 0; /* prefix size */
533       
534       if( (ps = isPrefixedWith( string, removerPrefixes )) != 0 ) {
535          ret = string.substring( ps );
536       } else if ( (ps = isPrefixedWith( string, adderPrefixes )) != 0 ) {
537          ret = string.substring( ps );
538       } else if ( (ps = isPrefixedWith( string, setterPrefixes )) != 0 ) {
539          ret = string.substring( ps );
540       } else if ( (ps = isPrefixedWith( string, getterPrefixes )) != 0 ) {
541          ret = string.substring( ps );
542       }
543
544       return ret;
545    }
546
547    /**
548     * Returns the field name for a given method (modifier or getter).
549     *
550     * @param cl the class where the method is supposed to be
551     * @param method the name of the method
552     * @return the field for this method if exist */

553
554    public static String JavaDoc fieldForMethod(Class JavaDoc cl, String JavaDoc method) {
555       if ( (!isGetter(method)) && (!isModifier(method)) )
556          return null;
557       String JavaDoc fieldName1 = getUnderscoredString(
558          getUnprefixedString( method ) );
559       Hashtable fields = ClassRepository.getDirectFieldAccess(cl);
560       if (fields.containsKey(fieldName1))
561          return fieldName1;
562       String JavaDoc fieldName2 = lowerFirst(getUnprefixedString(method));
563       if (fields.containsKey(fieldName2))
564          return fieldName2;
565       return null;
566    }
567
568    /**
569     * Returns the printable textual representation of a field or
570     * method name.
571     *
572     * @param name the field or method name
573     * @return a "natural-language-like" textual representation */

574
575    public static String JavaDoc textForName(String JavaDoc name) {
576       if (name.length()==0)
577      return name;
578       StringBuffer JavaDoc sb = new StringBuffer JavaDoc(name.length());
579       sb.append(Character.toUpperCase(name.charAt(0)) );
580       for (int i = 1; i<name.length(); i++) {
581          char c = name.charAt(i);
582          if ( Character.isUpperCase(c) &&
583               ( (i>0) && Character.isLowerCase(name.charAt(i-1)) ) ) {
584             sb.append ( ' ' );
585         if ( (i<name.length()-1) &&
586                  Character.isUpperCase(name.charAt(i+1)) ) {
587            sb.append(c);
588         } else {
589            sb.append(Character.toLowerCase(c));
590         }
591          } else {
592             if ( c == '_' || c == '.' || c == '-' ) {
593                sb.append(' ');
594             } else {
595                sb.append(c);
596             }
597          }
598       }
599       return new String JavaDoc(sb);
600    }
601
602    /**
603     * Returns the normalized name of an aspect regarding its class
604     * name.<p>
605     *
606     * E.g.:
607     *
608     * <ul>
609     * <li>AgendaPersistenceAC -> persistence
610     *
611     * @param name the aspect name to normalize
612     * @return the normalized name */

613
614    public static String JavaDoc getNormalizedAspectName(String JavaDoc name) {
615       if ( name == null ) return null;
616       if ( name.length() == 0 )
617          return name;
618       String JavaDoc result = null;
619       StringBuffer JavaDoc sb = new StringBuffer JavaDoc( name.length() );
620       for ( int i = 1; i < name.length(); i++ ) {
621          char c = name.charAt( i );
622          if ( Character.isUpperCase( c ) ) {
623             result = name.substring( i );
624             break;
625          }
626       }
627       if ( result == null ) return null;
628       result = result.substring( 0, result.length() - 2 );
629       return result.toLowerCase();
630    }
631
632    /**
633     * Returns the normalized class name of an aspect regarding its
634     * normalized name and the program it belongs to.<p>
635     *
636     * <ul>
637     * <li>org.objectweb.jac.samples.agenda, persistence -> AgendaPersistenceAC
638     *
639     * @param programName name of the application the aspect belongs to
640     * @param aspectName the aspect name to normalize
641     * @return the normalized name */

642
643    public static String JavaDoc getNormalizedAspectClassName(String JavaDoc programName,
644                                                      String JavaDoc aspectName) {
645       if (aspectName == null || aspectName.length() == 0)
646          return null;
647       String JavaDoc result = null;
648       String JavaDoc shortProgramName = programName.substring( programName.lastIndexOf( '.' ) );
649       StringBuffer JavaDoc sb1 = new StringBuffer JavaDoc( shortProgramName );
650       sb1.setCharAt( 1, Character.toUpperCase( sb1.charAt( 1 ) ) );
651       StringBuffer JavaDoc sb2 = new StringBuffer JavaDoc( aspectName );
652       sb2.setCharAt( 0, Character.toUpperCase( sb2.charAt( 0 ) ) );
653       result = programName + new String JavaDoc( sb1 ) + new String JavaDoc( sb2 ) + "AC";
654       return result;
655    }
656
657 }
658
Popular Tags