MethodScanner methodScanner = new MethodScanner(); MethodTree methodTree = methodScanner.scan(methodElement, this.trees); methodTree.getBody();
/** * This method is used to create a read only contact. A read only * contact object is used when there is constructor injection used * by the class schema. So, read only methods can be used in a * fully serializable and deserializable object. * * @param read this is the part to add as a read only contact */ private void build(MethodPart read) throws Exception { add(new MethodContact(read)); }
/** * This method is used to scan the class hierarchy for each class * in order to extract methods that contain XML annotations. If * a method is annotated it is converted to a contact so that * it can be used during serialization and deserialization. * * @param detail this contains the details for the class scanned */ private void scan(Detail detail) throws Exception { DefaultType override = detail.getOverride(); DefaultType access = detail.getAccess(); Class base = detail.getSuper(); if(base != null) { extend(base, override); } extract(detail, access); extract(detail); build(); validate(); }
process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); remove(method, label, list);
/** * Constructor for the <code>MethodScanner</code> object. This is * used to create an object that will scan the specified class * such that all bean property methods can be paired under the * XML annotation specified within the class. * * @param detail this contains the details for the class scanned * @param support this contains various support functions */ public MethodScanner(Detail detail, Support support) throws Exception { this.factory = new MethodPartFactory(detail, support); this.write = new PartMap(); this.read = new PartMap(); this.support = support; this.detail = detail; this.scan(detail); }
/** * This is used to classify the specified method into either a get * or set method. If the method is neither then an exception is * thrown to indicate that the XML annotations can only be used * with methods following the Java Bean naming conventions. Once * the method is classified is is added to either the read or * write map so that it can be paired after scanning is complete. * * @param method this is the method that is to be classified * @param label this is the annotation applied to the method * @param list this is the list of annotations on the method */ private void process(Method method, Annotation label, Annotation[] list) throws Exception { MethodPart part = factory.getInstance(method, label, list); MethodType type = part.getMethodType(); if(type == MethodType.GET) { process(part, read); } if(type == MethodType.IS) { process(part, read); } if(type == MethodType.SET) { process(part, write); } }
/** * This is used to acquire a list of <code>Contact</code> objects * that represent the annotated methods in a type. The entire * class hierarchy is scanned for annotated methods. Caching of * the contact list is done to increase performance. * * @param type this is the type to scan for annotated methods * @param detail this is the type to scan for annotated methods * * @return this returns a list of the annotated methods */ private ContactList getMethods(Class type, Detail detail) throws Exception { ContactList list = new MethodScanner(detail, support); if(detail != null) { methods.cache(type, list); } return list; } }
/** * This method is used to pair the get methods with a matching set * method. This pairs methods using the Java Bean method name, the * names must match exactly, meaning that the case and value of * the strings must be identical. Also in order for this to succeed * the types for the methods and the annotation must also match. * * @param read this is a get method that has been extracted * @param name this is the Java Bean methods name to be matched */ private void build(MethodPart read, String name) throws Exception { MethodPart match = write.take(name); if(match != null) { build(read, match); } else { build(read); } }
/** * This is used to process a method from a super class. Processing * the inherited method involves extracting out the individual * parts of the method an initializing the internal state of this * scanner. If method is overridden it overwrites the parts. * * @param contact this is a method inherited from a super class */ private void process(MethodContact contact) { MethodPart get = contact.getRead(); MethodPart set = contact.getWrite(); if(set != null) { insert(set, write); } insert(get, read); }
/** * This is used to insert a contact to this contact list. Here if * a <code>Text</code> annotation is declared on a method that * already has an annotation then the other annotation is given * the priority, this is to so text can be processes separately. * * @param method this is the part that is to be inserted * @param map this is the map that the part is to be inserted in */ private void insert(MethodPart method, PartMap map) { String name = method.getName(); MethodPart existing = map.remove(name); if(existing != null) { if(isText(method)) { method = existing; } } map.put(name, method); }
/** * This method is used to remove a particular method from the list * of contacts. If the <code>Transient</code> annotation is used * by any method then this method must be removed from the schema. * In particular it is important to remove methods if there are * defaults applied to the class. * * @param method this is the method that is to be removed * @param label this is the label associated with the method * @param list this is the list of annotations on the method */ private void remove(Method method, Annotation label, Annotation[] list) throws Exception { MethodPart part = factory.getInstance(method, label, list); MethodType type = part.getMethodType(); if(type == MethodType.GET) { remove(part, read); } if(type == MethodType.IS) { remove(part, read); } if(type == MethodType.SET) { remove(part, write); } }
/** * This is used to scan the declared methods within the specified * class. Each method will be checked to determine if it contains * an XML element and can be used as a <code>Contact</code> for * an entity within the object. * * @param detail this is one of the super classes for the object */ private void extract(Detail detail) throws Exception { List<MethodDetail> methods = detail.getMethods(); for(MethodDetail entry: methods) { Annotation[] list = entry.getAnnotations(); Method method = entry.getMethod(); for(Annotation label : list) { scan(method, label, list); } } }
/** * This method is used to extend the provided class. Extending a * class in this way basically means that the fields that have * been scanned in the specific class will be added to this. Doing * this improves the performance of classes within a hierarchy. * * @param base the class to inherit scanned fields from * @param access this is the access type used for the super type */ private void extend(Class base, DefaultType access) throws Exception { ContactList list = support.getMethods(base, access); for(Contact contact : list) { process((MethodContact)contact); } }
process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); process(method, label, list); remove(method, label, list);
/** * This is used to acquire a list of <code>Contact</code> objects * that represent the annotated methods in a type. The entire * class hierarchy is scanned for annotated methods. Caching of * the contact list is done to increase performance. * * @param type this is the type to scan for annotated methods * @param detail this is the type to scan for annotated methods * * @return this returns a list of the annotated methods */ private ContactList getMethods(Class type, Detail detail) throws Exception { ContactList list = new MethodScanner(detail, support); if(detail != null) { methods.cache(type, list); } return list; } }
/** * This method is used to pair the get methods with a matching set * method. This pairs methods using the Java Bean method name, the * names must match exactly, meaning that the case and value of * the strings must be identical. Also in order for this to succeed * the types for the methods and the annotation must also match. * * @param read this is a get method that has been extracted * @param name this is the Java Bean methods name to be matched */ private void build(MethodPart read, String name) throws Exception { MethodPart match = write.take(name); if(match != null) { build(read, match); } else { build(read); } }
/** * This is used to process a method from a super class. Processing * the inherited method involves extracting out the individual * parts of the method an initializing the internal state of this * scanner. If method is overridden it overwrites the parts. * * @param contact this is a method inherited from a super class */ private void process(MethodContact contact) { MethodPart get = contact.getRead(); MethodPart set = contact.getWrite(); if(set != null) { insert(set, write); } insert(get, read); }
/** * This is used to insert a contact to this contact list. Here if * a <code>Text</code> annotation is declared on a method that * already has an annotation then the other annotation is given * the priority, this is to so text can be processes separately. * * @param method this is the part that is to be inserted * @param map this is the map that the part is to be inserted in */ private void insert(MethodPart method, PartMap map) { String name = method.getName(); MethodPart existing = map.remove(name); if(existing != null) { if(isText(method)) { method = existing; } } map.put(name, method); }
/** * This method is used to remove a particular method from the list * of contacts. If the <code>Transient</code> annotation is used * by any method then this method must be removed from the schema. * In particular it is important to remove methods if there are * defaults applied to the class. * * @param method this is the method that is to be removed * @param label this is the label associated with the method * @param list this is the list of annotations on the method */ private void remove(Method method, Annotation label, Annotation[] list) throws Exception { MethodPart part = factory.getInstance(method, label, list); MethodType type = part.getMethodType(); if(type == MethodType.GET) { remove(part, read); } if(type == MethodType.IS) { remove(part, read); } if(type == MethodType.SET) { remove(part, write); } }
/** * This method is used to scan the class hierarchy for each class * in order to extract methods that contain XML annotations. If * a method is annotated it is converted to a contact so that * it can be used during serialization and deserialization. * * @param detail this contains the details for the class scanned */ private void scan(Detail detail) throws Exception { DefaultType override = detail.getOverride(); DefaultType access = detail.getAccess(); Class base = detail.getSuper(); if(base != null) { extend(base, override); } extract(detail, access); extract(detail); build(); validate(); }