View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.orchestra.annotation;
20  
21  import java.lang.reflect.Method;
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.myfaces.orchestra.conversation.annotations.ConversationName;
28  import org.apache.myfaces.orchestra.conversation.annotations.ConversationRequire;
29  import org.apache.myfaces.orchestra.viewController.annotations.InitView;
30  import org.apache.myfaces.orchestra.viewController.annotations.PreProcess;
31  import org.apache.myfaces.orchestra.viewController.annotations.PreRenderView;
32  import org.apache.myfaces.orchestra.viewController.annotations.ViewController;
33  
34  /**
35   * Inspects a class for Orchestra annotations, and if found then caches this information
36   * for later access.
37   * <p>
38   * The processing of Class objects is expected to happen only at application startup.
39   * <p>
40   * Note that annotation scanning is driven by the dependency-injection framework, i.e.
41   * only classes declared to the framework are scanned. 
42   */
43  public class AnnotationInfoManager
44  {
45      private final Log log = LogFactory.getLog(AnnotationInfoManager.class);
46  
47      private Map<String, AnnotationInfo> annotationsInfoByName = new HashMap<String, AnnotationInfo>();
48      private Map<String, AnnotationInfo> annotationsInfoByViewId = new HashMap<String, AnnotationInfo>();
49  
50      protected void addAnnotationsInfo(AnnotationInfo annotationInfo)
51      {
52          if (annotationsInfoByName.containsKey(annotationInfo.getBeanName()))
53          {
54              if (log.isInfoEnabled())
55              {
56                  log.info("duplicate bean definition: " + annotationInfo.getBeanName());
57              }
58          }
59  
60          annotationsInfoByName.put(annotationInfo.getBeanName(), annotationInfo);
61  
62          ViewController viewController = annotationInfo.getViewController();
63          if (viewController != null)
64          {
65              String[] viewIds = viewController.viewIds();
66              for (int i = 0; i<viewIds.length; i++)
67              {
68                  String viewId = viewIds[i];
69  
70                  if (log.isInfoEnabled())
71                  {
72                      if (annotationsInfoByViewId.containsKey(annotationInfo.getBeanName()))
73                      {
74                          log.info("duplicate viewId definition: " + annotationInfo.getBeanName());
75                      }
76                  }
77  
78                  annotationsInfoByViewId.put(viewId, annotationInfo);
79              }
80          }
81      }
82  
83      public AnnotationInfo getAnnotationInfoByBeanName(String beanName)
84      {
85          return annotationsInfoByName.get(beanName);
86      }
87  
88      public AnnotationInfo getAnnotationInfoByViewId(String viewId)
89      {
90          return annotationsInfoByViewId.get(viewId);
91      }
92  
93      /**
94       * Inspect the provided class for annotations, and if found then cache the info
95       * keyed by the specified beanName.
96       * <p>
97       * Currently the class-level annotations looked for are:
98       * <ul>
99       * <li>ConversationName
100      * <li>ConversationRequire
101      * <li>ViewController
102      * </ul>
103      * <p>
104      * If the ViewController annotation is present, then the class is also scanned
105      * for related annotations on class methods.
106      */
107     public void processBeanAnnotations(String beanName, Class<?> clazz)
108     {
109         ConversationName conversationName = (ConversationName) clazz.getAnnotation(ConversationName.class);
110         ViewController viewController = (ViewController) clazz.getAnnotation(ViewController.class);
111         ConversationRequire conversationRequire = (ConversationRequire) clazz.getAnnotation(ConversationRequire.class);
112 
113         if (conversationName == null && viewController == null && conversationRequire == null)
114         {
115             return;
116         }
117 
118         AnnotationInfo annotationInfo = new AnnotationInfo(beanName, clazz);
119         annotationInfo.setConversationName(conversationName);
120         annotationInfo.setConversationRequire(conversationRequire);
121         
122         if (viewController != null)
123         {
124             annotationInfo.setViewController(viewController);
125             Method[] methods = clazz.getMethods();
126             for (int i = 0; i<methods.length; i++)
127             {
128                 Method method = methods[i];
129                 if (method.isAnnotationPresent(InitView.class))
130                 {
131                     annotationInfo.setInitViewMethod(method);
132                 }
133                 if (method.isAnnotationPresent(PreProcess.class))
134                 {
135                     annotationInfo.setPreProcessMethod(method);
136                 }
137                 if (method.isAnnotationPresent(PreRenderView.class))
138                 {
139                     annotationInfo.setPreRenderViewMethod(method);
140                 }
141             }
142         }
143 
144         addAnnotationsInfo(annotationInfo);
145     }
146 }