View Javadoc

1   package org.cateproject.controller.flow.action.upload;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.List;
6   import java.util.Map;
7   
8   import org.apache.log4j.Logger;
9   import org.springframework.beans.BeanWrapperImpl;
10  import org.springframework.beans.InvalidPropertyException;
11  import org.springframework.beans.NullValueInNestedPathException;
12  import org.springframework.core.convert.ConversionService;
13  import org.springframework.util.ReflectionUtils;
14  
15  import eu.etaxonomy.cdm.api.service.ITermService;
16  import eu.etaxonomy.cdm.model.common.DefinedTermBase;
17  import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
18  import eu.etaxonomy.cdm.persistence.query.OrderHint;
19  import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;
20  
21  public class AbstractMatrixHeader<T extends IdentifiableEntity> implements Serializable, Comparable<AbstractMatrixHeader<T>> {
22  	/**
23  	 * 
24  	 */
25  	private static final long serialVersionUID = 1L;
26  
27  	protected static Logger logger = Logger.getLogger(AbstractMatrixHeader.class);
28  	
29  	private int index;
30  	private String fullPath;
31  	private String path;
32  	
33  	private String label;
34  	private AbstractMatrixHeaderType type;
35  	private Class<T> clazz;
36      private List<Class> classes;
37      private List<HeaderPath> paths = new ArrayList<HeaderPath>();
38      private List<DefinedTermBase> terms = new ArrayList<DefinedTermBase>();
39  
40  	private boolean set = false;
41  
42  	public AbstractMatrixHeader(String path, int index, Class<T> clazz, Map<Class,List<Class>> classes, ITermService termService) {;
43  		this.label = path;
44  		this.index = index;
45  		this.clazz = clazz;
46  
47  		this.fullPath = path;
48  		
49  		if(path.endsWith(".class")) {
50  			this.path = path.substring(0, path.lastIndexOf(".class"));
51  			this.type = AbstractMatrixHeaderType.CLASS;
52  		} else if(path.equals("class")) {
53  			this.path = "";
54  			this.type = AbstractMatrixHeaderType.ROOT_CLASS;
55  		}else {
56  			this.type = AbstractMatrixHeaderType.PROPERTY;
57  			this.path = path;
58  		}
59  		logger.info("Constructing header for " + path + " " + clazz + " " + classes.get(clazz)); 
60  		HeaderPath p = new HeaderPath(clazz, classes.get(clazz), path);
61  		this.paths.add(p);
62  		while(!p.isTerminating()) {
63  			if(classes.containsKey(p.getPropertyType())) {
64  				p = new HeaderPath(p.getPropertyType(),classes.get(p.getPropertyType()),p.getRemainingPath());
65  			} else { 
66  				p = new HeaderPath(p.getPropertyType(),p.getRemainingPath());
67  			}
68  			this.paths.add(p);
69  		}
70  		
71  		Class terminalPropertyType = this.paths.get(this.paths.size() - 1).getPropertyType();
72  		
73  		if(terminalPropertyType != null && DefinedTermBase.class.isAssignableFrom(terminalPropertyType)) {
74  			List<OrderHint> orderHints = new ArrayList<OrderHint>();
75  			orderHints.add(new OrderHint("titleCache",SortOrder.ASCENDING));
76  		    this.terms = termService.list(terminalPropertyType, null, null, orderHints, null);		
77  		}
78  		
79  	}
80  	
81  	public boolean isNested() {
82  		return this.paths.get(0).isTerminating();
83  	}
84  	
85  	public HeaderPath[] getPaths() {
86  		return this.paths.toArray(new HeaderPath[this.paths.size()]);
87  	}
88  	
89  
90  	public MatrixHeader<T> getHeaderForObject(T o, ConversionService conversionService) {
91  		if(this.isApplicable(o,conversionService)) {
92  			if(this.getType().equals(AbstractMatrixHeaderType.ROOT_CLASS)) {
93  				return new RootClassMatrixHeader<T>(clazz);
94  			} else if(this.getType().equals(AbstractMatrixHeaderType.CLASS)) {
95  				return new ClassMatrixHeader<T>(this.path,this.paths,o);
96  			} else {
97  		        return new PropertyMatrixHeader<T>(this.path,this.paths,o,terms);
98  			}
99  		} else {
100 			return null;
101 		}
102 	}
103 
104 	public boolean isApplicable(Object o, ConversionService conversionService) {
105 		if(this.type.equals(AbstractMatrixHeaderType.ROOT_CLASS)) {
106 			return true;
107 		} else if(this.type.equals(AbstractMatrixHeaderType.CLASS) && this.paths.get(0).isCollection()) { 
108 			if(ReflectionUtils.findField(o.getClass(), this.paths.get(0).getProperty()) != null) {			
109 			    return true;
110 			} else {
111 				return false;
112 			}
113 		} else {
114 		  BeanWrapperImpl beanWrapperImpl = new BeanWrapperImpl(o);
115 		  beanWrapperImpl.setAutoGrowNestedPaths(true);
116 		  beanWrapperImpl.setConversionService(conversionService);
117 		  try {
118 				beanWrapperImpl.getPropertyDescriptor(this.path);
119 				return true; // this property can be found in the current object;
120 		  } catch(IllegalArgumentException iae) { 
121 			  logger.info(iae.getMessage());
122 			  return false; // the property is null;
123 		  } catch(NullValueInNestedPathException nvinpe) {
124 			  logger.info(nvinpe.getMessage());
125 			  return false;
126 		  } catch(InvalidPropertyException ipe) {
127 			  logger.info(ipe.getMessage());
128 			  return false;
129 		  }
130 		}
131 	}
132 
133 	public boolean isClassType() {
134 		return type.equals(AbstractMatrixHeaderType.CLASS);
135 	}
136 	
137 	public boolean isObjectType() {
138 		return type.equals(AbstractMatrixHeaderType.PROPERTY);
139 	}
140 
141 	public int getIndex() {
142 		return index;
143 	}
144 	
145 	public String getLabel() {
146 		return this.label;
147 	}
148 
149 	public String getPath(String prefix) {
150 		if(path == "") {
151 			return prefix;
152 		}
153 		return prefix + "." + path;
154 	}
155 	
156 	protected String getPath() {
157 		return path;
158 	}
159 
160 	public int compareTo(AbstractMatrixHeader o) {
161 		if(this.path.contains(".")) {
162 			if(!o.getPath().contains(".")) {
163 				return -1;
164 			} else{
165 			  String path1 = this.path.substring(0,this.path.lastIndexOf("."));
166 			  String path2 = o.getPath().substring(0, o.getPath().lastIndexOf("."));
167 			  if(path1.equals(path2)) {
168 				  String property1 = this.path.substring(this.path.lastIndexOf(".") + 1);
169 				  String property2 = o.getPath().substring(o.getPath().lastIndexOf(".") + 1);
170 				  if(property1.equals("class") && property2.contains("class")) {
171 						return 0;
172 					  } else if(property1.equals("class")) { 
173 						return 1;				
174 					  } else if(property2.equals("class")) {
175 						return -1;
176 					  } else {
177 						return property1.compareTo(property2);
178 					  }
179 			  } else{
180 				  return path1.compareTo(path2);
181 			  }
182 			}
183 		} else {
184 			if(o.getPath().contains(".")) {
185 				return 1;
186 			} else {
187 			  if(this.path.equals("class") && o.getPath().contains("class")) {
188 				return 0;
189 			  } else if(this.path.equals("class")) { 
190 				return 1;				
191 			  } else if(o.getPath().equals("class")) {
192 				return -1;
193 			  } else {
194 				return this.path.compareTo(o.getPath());
195 			  }
196 			}
197 		}
198 	}
199 
200 	public AbstractMatrixHeaderType getType() {
201 		return type;
202 	}
203 
204 	public List<DefinedTermBase> getTerms() {
205 		return terms;
206 	}
207 
208 	public Class<T> getClazz() {
209 		return clazz;
210 	}
211 
212 	public Class getFieldType() {
213 		return this.paths.get(this.paths.size() - 1).getPropertyType();
214 	}
215 
216 	public boolean isSet() {
217 		if(this.paths.size() == 1) {
218 			return false;
219 		} else {
220     		return this.paths.get(this.paths.size() - 2).isSet();
221 		}
222 	}
223 
224 	public boolean isMap() {
225 		if(this.paths.size() == 1) {
226 			return false;
227 		} else {
228     		return this.paths.get(this.paths.size() - 2).isMap();
229 		}
230 	}
231 }