View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.core.execution;
17  
18  import java.io.Serializable;
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.argeo.slc.execution.ExecutionSpec;
27  import org.argeo.slc.execution.ExecutionSpecAttribute;
28  import org.springframework.beans.factory.BeanNameAware;
29  import org.springframework.beans.factory.InitializingBean;
30  import org.springframework.beans.factory.NoSuchBeanDefinitionException;
31  import org.springframework.beans.factory.config.BeanDefinition;
32  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
33  import org.springframework.context.ApplicationContext;
34  import org.springframework.context.ApplicationContextAware;
35  import org.springframework.context.ConfigurableApplicationContext;
36  
37  /** Spring based implementation of execution specifications. */
38  public class DefaultExecutionSpec implements ExecutionSpec, BeanNameAware,
39  		ApplicationContextAware, InitializingBean, Serializable {
40  	private static final long serialVersionUID = 5159882223926926539L;
41  	private final static Log log = LogFactory
42  			.getLog(DefaultExecutionSpec.class);
43  	private transient ApplicationContext applicationContext;
44  
45  	private String description;
46  	private Map<String, ExecutionSpecAttribute> attributes = new HashMap<String, ExecutionSpecAttribute>();
47  
48  	private String name = INTERNAL_NAME;
49  
50  	public Map<String, ExecutionSpecAttribute> getAttributes() {
51  		return attributes;
52  	}
53  
54  	public void setAttributes(Map<String, ExecutionSpecAttribute> attributes) {
55  		this.attributes = attributes;
56  	}
57  
58  	public void setBeanName(String name) {
59  		this.name = name;
60  	}
61  
62  	/**
63  	 * The Spring bean name (only relevant for specs declared has high-level
64  	 * beans)
65  	 */
66  	public String getName() {
67  		return name;
68  	}
69  
70  	public boolean equals(Object obj) {
71  		return ((ExecutionSpec) obj).getName().equals(name);
72  	}
73  
74  	/**
75  	 * The Spring bean description (only relevant for specs declared has
76  	 * high-level beans)
77  	 */
78  	public String getDescription() {
79  		return description;
80  	}
81  
82  	private ConfigurableListableBeanFactory getBeanFactory() {
83  		return ((ConfigurableApplicationContext) applicationContext)
84  				.getBeanFactory();
85  	}
86  
87  	public void setApplicationContext(ApplicationContext applicationContext) {
88  		this.applicationContext = applicationContext;
89  	}
90  
91  	public void afterPropertiesSet() throws Exception {
92  		if (description == null) {
93  			try {
94  				description = getBeanFactory().getBeanDefinition(name)
95  						.getDescription();
96  			} catch (NoSuchBeanDefinitionException e) {
97  				// silent
98  			}
99  		}
100 
101 		for (String key : attributes.keySet()) {
102 			ExecutionSpecAttribute attr = attributes.get(key);
103 			if (attr instanceof RefSpecAttribute) {
104 				RefSpecAttribute rsa = (RefSpecAttribute) attr;
105 				if (rsa.getChoices() == null) {
106 					List<RefValueChoice> choices = buildRefValueChoices(rsa);
107 					rsa.setChoices(choices);
108 				}
109 				if (log.isTraceEnabled())
110 					log.debug("Spec attr " + key + " has "
111 							+ rsa.getChoices().size() + " choices");
112 			}
113 		}
114 	}
115 
116 	/**
117 	 * Generates a list of ref value choices based on the bean available in the
118 	 * application ocntext.
119 	 */
120 	protected List<RefValueChoice> buildRefValueChoices(RefSpecAttribute rsa) {
121 		List<RefValueChoice> choices = new ArrayList<RefValueChoice>();
122 		if (applicationContext == null) {
123 			log.warn("No application context declared,"
124 					+ " cannot scan ref value choices.");
125 			return choices;
126 		}
127 
128 		beanNames: for (String beanName : getBeanFactory().getBeanNamesForType(
129 				rsa.getTargetClass(), true, false)) {
130 
131 			// Since Spring 3, systemProperties is implicitly defined but has no
132 			// bean definition
133 			if (beanName.equals("systemProperties"))
134 				continue beanNames;
135 
136 			BeanDefinition bd = getBeanFactory().getBeanDefinition(beanName);
137 			RefValueChoice choice = new RefValueChoice();
138 			choice.setName(beanName);
139 			choice.setDescription(bd.getDescription());
140 			if (log.isTraceEnabled())
141 				log.debug("Found choice " + beanName + " for " + rsa);
142 
143 			choices.add(choice);
144 
145 		}
146 		return choices;
147 	}
148 
149 }