001 package org.kuali.student.common.assembly.transform;
002
003 import java.util.ArrayList;
004 import java.util.HashMap;
005 import java.util.List;
006 import java.util.Map;
007
008 import org.apache.log4j.Logger;
009 import org.kuali.student.common.assembly.data.Data;
010 import org.kuali.student.common.assembly.data.Metadata;
011 import org.kuali.student.common.assembly.dictionary.MetadataServiceImpl;
012 import org.kuali.student.common.dto.DtoConstants;
013
014 public class TransformationManager {
015 final Logger LOG = Logger.getLogger(TransformationManager.class);
016
017 private MetadataServiceImpl metadataService;
018 private DataBeanMapper mapper = new DefaultDataBeanMapper();
019 private List<TransformFilter> filterList = new ArrayList<TransformFilter>();
020
021 private static ThreadLocal<Metadata> metadataCache = new ThreadLocal<Metadata>();
022
023 /**
024 * This is an outbound transform request which will convert incoming DTO objects
025 * to a Data map and apply outbound filter operation to both the data object
026 * and the converted DTO object.
027 *
028 * @param value
029 * @return
030 * @throws Exception
031 */
032 public Data transform(Object value) throws Exception{
033 applyOutboundFilters(value.getClass().getName(), value, new HashMap<String,Object>());
034 Data dataValue = mapper.convertFromBean(value);
035 applyOutboundFilters(value.getClass().getName(), dataValue, new HashMap<String,Object>());
036
037 return dataValue;
038 }
039
040 public Data transform(Object value, Map<String,Object> filterProperties) throws Exception{
041 applyOutboundFilters(value.getClass().getName(), value, filterProperties);
042 Data dataValue = mapper.convertFromBean(value);
043 applyOutboundFilters(value.getClass().getName(), dataValue, filterProperties);
044
045 return dataValue;
046 }
047
048
049 /**
050 * This is an inbound transform request which will convert incoming Data objects
051 * to the corresponding DTO object and apply inbound filter operations to both the data object
052 * and the converted DTO object.
053 *
054 * @param value The incoming Data value to transform to DTO object
055 * @param clazz The DTO object class represented by the Data value
056 * @return The converted DTO with both inbound Data and DTO filters applied.
057 */
058 public Object transform(Data value, Class<?> clazz) throws Exception{
059 Metadata metadata = null;
060 metadata = (metadata != null ? metadata:getMetadata(clazz.getName(), new HashMap<String,Object>()));
061 applyInboundFilters(clazz.getName(), value, new HashMap<String,Object>(),metadata);
062 Object dtoValue = mapper.convertFromData(value, clazz,metadata);
063 applyInboundFilters(clazz.getName(), dtoValue, new HashMap<String,Object>(),metadata);
064
065 return dtoValue;
066 }
067
068 /**
069 * This is an inbound transform request which will convert incoming Data objects
070 * to the corresponding DTO object and apply inbound filters to both the data object
071 * and the converted DTO object.
072 *
073 * @param value The incoming Data value to transform to DTO object
074 * @param clazz The DTO object class represented by the Data value
075 * @param filterProperties properties that can be consumed by the filters
076 * @return The converted DTO with both inbound Data and DTO filters applied.
077 */
078 public Object transform(Data value, Class<?> clazz, Map<String,Object> filterProperties) throws Exception{
079 Metadata metadata = null;
080 metadata = (metadata != null ? metadata:getMetadata(clazz.getName(), filterProperties));
081 metadataCache.set(metadata);
082 applyInboundFilters(clazz.getName(), value, filterProperties,metadata);
083 Object dtoValue = mapper.convertFromData(value, clazz,metadata);
084 applyInboundFilters(clazz.getName(), dtoValue, filterProperties,metadata);
085 return dtoValue;
086 }
087
088 /**
089 * This method applies all inbound filters known to his transformation manager.
090 *
091 * @param dtoName The name of the dto represented by a Data value, for Dto values,
092 * this can simply be the name of the dto class
093 * @param value The dto or data object to apply filters to
094 * @throws Exception
095 */
096 public void applyInboundFilters(String dtoName, Object value, Map<String,Object> properties, Metadata metadata) throws Exception{
097 for (TransformFilter filter:filterList){
098 if (filter.getType().isInstance(value)){
099 if (filter instanceof AbstractDataFilter) {
100 ((AbstractDataFilter)filter).applyInboundDataFilter((Data)value, metadata, properties);
101 } else {
102 ((AbstractDTOFilter)filter).applyInboundDtoFilter(value, properties);
103 }
104 LOG.info(filter.getClass().getName() + ": Filter Applied");
105 }
106 }
107 }
108
109 /**
110 * This method applies all outbound filters known to his transformation manager.
111 *
112 * @param dtoName The name of the dto represented by a Data value, for Dto values,
113 * this can simply be the name of the dto class
114 * @param value The dto or data object to apply filters to
115 * @throws Exception
116 */
117 public void applyOutboundFilters(String dtoName, Object value, Map<String,Object> properties) throws Exception{
118 Metadata metadata = metadataCache.get();
119
120 for (TransformFilter filter:filterList){
121 if (filter.getType().isInstance(value)){
122 if (filter instanceof AbstractDataFilter) {
123 metadata = (metadata != null ? metadata:getMetadata(dtoName, properties));
124 ((AbstractDataFilter)filter).applyOutboundDataFilter((Data)value, metadata, properties);
125 } else {
126 ((AbstractDTOFilter)filter).applyOutboundDtoFilter(value, properties);
127 }
128 LOG.info(filter.getClass().getName() + ": Filter Applied");
129 }
130 }
131 }
132
133 public Metadata getMetadata(String dtoName, Map<String,Object> filterProperties){
134 String state = (String)filterProperties.get(DtoConstants.DTO_STATE);
135 String nextState = (String)filterProperties.get(DtoConstants.DTO_NEXT_STATE);
136
137 Metadata metadata = metadataService.getMetadata(dtoName, null, state, nextState);
138
139 applyMetadataFilters(dtoName, metadata, filterProperties);
140 return metadata;
141 }
142
143 public void applyMetadataFilters(String dtoName, Metadata metadata, Map<String, Object> filterProperties){
144 for (TransformFilter filter:filterList){
145 if (filter instanceof MetadataFilter){
146 ((MetadataFilter) filter).applyMetadataFilter(dtoName, metadata, filterProperties);
147 }
148 }
149 }
150
151 public Metadata getUnfilteredMetadata(String dtoName){
152 Metadata metadata = metadataService.getMetadata(dtoName);
153 return metadata;
154 }
155
156 public void setMetadataService(MetadataServiceImpl metadataService) {
157 this.metadataService = metadataService;
158 }
159
160 public void addFilter(TransformFilter filter){
161 filterList.add(filter);
162 }
163
164 public void setFilters(List<TransformFilter> filters){
165 filterList.addAll(filters);
166 }
167
168 public void removeFilter(TransformFilter filter){
169 filterList.remove(filter);
170 }
171 }