]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.ws.client/src/main/java/org/argeo/slc/ant/spring/SpringArg.java
Introduce org.argeo.slc.lib.detached
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.ws.client / src / main / java / org / argeo / slc / ant / spring / SpringArg.java
1 package org.argeo.slc.ant.spring;
2
3 import java.util.List;
4 import java.util.Vector;
5
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
8 import org.apache.tools.ant.types.DataType;
9 import org.argeo.slc.ant.AntConstants;
10 import org.argeo.slc.core.SlcException;
11 import org.springframework.beans.BeanWrapper;
12 import org.springframework.beans.BeanWrapperImpl;
13 import org.springframework.beans.factory.InitializingBean;
14 import org.springframework.context.ApplicationContext;
15
16 /** Abstract Ant type wrapping a Spring bean. */
17 public class SpringArg<T> extends DataType {
18 private final static Log log = LogFactory.getLog(SpringArg.class);
19
20 private List<OverrideArg> overrides = new Vector<OverrideArg>();
21
22 private String bean;
23 private String antref;
24 /**
25 * Reference to the original object, used to merge overrides. <b>this object
26 * will be modified</b>.
27 */
28 private T original;
29
30 // cache bean instance to avoid reading it twice if it is a prototype
31 private T instance = null;
32
33 /** The <u>name</u> of the underlying bean, as set through the attribute. */
34 public String getBean() {
35 return bean;
36 }
37
38 /** Setter for the bean name. */
39 public void setBean(String bean) {
40 checkValueAlreadySet();
41 this.bean = bean;
42 }
43
44 public String getAntref() {
45 return antref;
46 }
47
48 /** Sets a reference to an ant data type. */
49 public void setAntref(String antref) {
50 checkValueAlreadySet();
51 this.antref = antref;
52 }
53
54 /**
55 * Retrieve the instance of the bean, and sets the overridden properties.
56 * <b>The value is cached.</b>
57 */
58 public T getInstance() {
59 if (instance == null) {
60 if (log.isTraceEnabled())
61 log.trace(this + "\t: Creates instance");
62
63 if (bean != null) {
64 instance = (T) getContext().getBean(bean);
65 if (instance == null)
66 throw new SlcException("No object found for Spring bean "
67 + bean);
68 } else if (antref != null) {
69 instance = (T) getProject().getReference(antref);
70 if (instance == null)
71 throw new SlcException("No object found for Ant reference "
72 + antref);
73 } else if (original != null) {
74 instance = original;
75 } else {
76 throw new SlcException(
77 "Don't know how to retrieve bean instance");
78 }
79
80 setOverridenProperties(instance);
81
82 // FIXME: why are we doing this? Could not find any object using it
83 if (instance instanceof InitializingBean) {
84 try {
85 ((InitializingBean) instance).afterPropertiesSet();
86 } catch (Exception e) {
87 throw new SlcException("Could not initialize bean", e);
88 }
89 }
90 } else {
91 if (log.isTraceEnabled())
92 log.trace(this + "\t: Returns cached instance");
93 }
94 return instance;
95 }
96
97 protected void setOverridenProperties(Object obj) {
98 BeanWrapper wrapper = new BeanWrapperImpl(obj);
99 for (OverrideArg override : overrides) {
100 if (override.getName() == null) {
101 throw new SlcException(
102 "The name of the property to override has to be set.");
103 }
104
105 if (log.isTraceEnabled())
106 log.trace(this + "\t: Overrides property " + override.getName()
107 + " with " + override);
108
109 if (override.getMerge() == true) {
110 // if override is marked as merged retrieve the value and set is
111 // as original
112 override.setOriginal(wrapper.getPropertyValue(override
113 .getName()));
114 }
115 wrapper.setPropertyValue(override.getName(), override.getObject());
116 }
117
118 }
119
120 /** Creates an override subtag. */
121 public OverrideArg createOverride() {
122 OverrideArg propertyArg = new OverrideArg();
123 overrides.add(propertyArg);
124 return propertyArg;
125 }
126
127 /** The related Spring application context. */
128 protected ApplicationContext getContext() {
129 return (ApplicationContext) getProject().getReference(
130 AntConstants.REF_ROOT_CONTEXT);
131 }
132
133 protected void checkValueAlreadySet() {
134 if (antref != null || bean != null || original != null) {
135 throw new SlcException("Instance value already defined.");
136 }
137 }
138
139 public void setOriginal(T original) {
140 checkValueAlreadySet();
141 this.original = original;
142 }
143
144 public T getOriginal() {
145 return original;
146 }
147
148 @Override
149 public String toString() {
150 StringBuffer buf = new StringBuffer(getClass().getSimpleName());
151 if (bean != null) {
152 buf.append("#bean=").append(bean);
153 } else if (antref != null) {
154 buf.append("#antref=").append(antref);
155 } else if (original != null) {
156 buf.append("#orig=").append(original.hashCode());
157 } else {
158 buf.append("#noid");
159 }
160 buf.append("#").append(hashCode());
161 return buf.toString();
162 }
163 }