View Javadoc

1   /*
2    * Copyright 2004-2006 the Seasar Foundation and the Others.
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, 
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.tuigwaa.model.common;
17  
18  import java.beans.IntrospectionException;
19  import java.beans.PropertyDescriptor;
20  import java.util.ArrayList;
21  import java.util.Date;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  
27  import javassist.CannotCompileException;
28  import javassist.ClassPool;
29  import javassist.NotFoundException;
30  
31  import org.apache.commons.beanutils.PropertyUtils;
32  import org.seasar.framework.util.ClassPoolUtil;
33  import org.seasar.tuigwaa.util.TgwNameUtils;
34  
35  import com.isenshi.util.CharUtil;
36  
37  /***
38   * @author someda
39   */
40  public class TgwJavaClassUtils {
41  	
42  	public static Class checkClass(String className) throws ClassNotFoundException{
43  		
44  		Class srcClass = Class.forName(className);
45  		Class destClass = srcClass;
46  		
47  		List dateClassPropertyList = new ArrayList();
48  		PropertyDescriptor[] descs = PropertyUtils.getPropertyDescriptors(srcClass);		
49  		for(int i=0;i<descs.length;i++){
50  			PropertyDescriptor desc = descs[i];
51  			if(desc.getReadMethod() != null && desc.getWriteMethod() != null){
52  				if(desc.getPropertyType().equals(Date.class)){
53  					dateClassPropertyList.add(desc);
54  				}				
55  			}						
56  		}		
57  		destClass = enhanceClass(srcClass,dateClassPropertyList);
58  		return destClass;
59  	}		
60  		
61  	public static Class addPropertyToClass(Class srcClass, Map propertyMap){
62  		
63  		if(propertyMap.size() == 0){
64  			return srcClass;
65  		}
66  		
67  		ClassPool cp = ClassPoolUtil.getClassPool(null);
68  		String enhancedClassName = TgwNameUtils.getEnhancedClassName(srcClass,propertyMap.hashCode());
69  		PojoClassGenerator generator = null;
70  		try{
71  			return Class.forName(enhancedClassName);	
72  		}catch(ClassNotFoundException cnfe){
73  			generator = new PojoClassGenerator(cp,srcClass,enhancedClassName);
74  		}
75  		
76  		try{
77  			addProperties(generator,propertyMap);
78  		}catch(ClassNotFoundException cnfe){
79  			cnfe.printStackTrace();
80  			throw new RuntimeException(cnfe);
81  		}catch(CannotCompileException cce){
82  			cce.printStackTrace();
83  			throw new RuntimeException(cce);
84  		}				
85  		return generator.toClass();
86  	}
87  	
88  	private static Class enhanceClass(Class srcClass, List dateClassPropertyList){
89  		
90  		if(dateClassPropertyList.size() == 0){
91  			return srcClass;
92  		}
93  		
94  		ClassPool cp = ClassPoolUtil.getClassPool(null);
95  		String enhancedClassName = TgwNameUtils.getEnhancedClassName(srcClass,dateClassPropertyList.hashCode());
96  		PojoClassGenerator generator = null;
97  		
98  		try{
99  			return Class.forName(enhancedClassName);	
100 		}catch(ClassNotFoundException cnfe){
101 			generator = new PojoClassGenerator(cp,srcClass,enhancedClassName);
102 		}				
103 		Map propertyMap = buildDatePropertyMap(srcClass,dateClassPropertyList);
104 		
105 		try{
106 			addProperties(generator,propertyMap);
107 			
108 			for(Iterator i=dateClassPropertyList.iterator();i.hasNext();){
109 				PropertyDescriptor desc = (PropertyDescriptor) i.next();
110 				String propertyName = desc.getName();			
111 				String setterName = "set" + CharUtil.toUpperCaseAtFisrtChar(propertyName);				
112 				String methodBody = buildDateAccessorMethodBody(propertyName);
113 				overrideMethod(generator,setterName,methodBody);
114 			}	
115 			
116 		}catch(CannotCompileException cce){
117 			cce.printStackTrace();
118 			throw new RuntimeException(cce);
119 		}catch(ClassNotFoundException cnfe){
120 			cnfe.printStackTrace();
121 			throw new RuntimeException(cnfe);			
122 		}catch(NotFoundException nfe){
123 			nfe.printStackTrace();
124 			throw new RuntimeException(nfe);			
125 		}		
126 		return generator.toClass();
127 	}	
128 	
129 	
130 	// ----- [private] -----
131 	
132 	private static final void addProperties(PojoClassGenerator generator, Map propertyMap) 
133 	throws CannotCompileException,ClassNotFoundException{
134 		for(Iterator i = propertyMap.keySet().iterator();i.hasNext();){
135 			String propertyName = (String)i.next();
136 			String propertyClassName = (String)propertyMap.get(propertyName);
137 			generator.addProperty(propertyName,propertyClassName);
138 		}		
139 	}
140 	
141 	private static final void overrideMethod(PojoClassGenerator generator, String methodName, String methodBody) 
142 	throws NotFoundException, CannotCompileException{		
143 		generator.overrideMethod(methodName,methodBody);
144 	}
145 	
146 	private static final String buildDateAccessorMethodBody(String propertyName){
147 		return "{" +
148 		"super.set" +  CharUtil.toUpperCaseAtFisrtChar(propertyName) +  "($1);" + 
149 		"java.util.Calendar cal = java.util.Calendar.getInstance();" +
150 		"if($1 != null) {cal.setTime($1);}" +
151 		"Integer calendarDay = new Integer(cal.get(java.util.Calendar.DATE));" +
152 		"Integer calendarMonth = new Integer(cal.get(java.util.Calendar.MONTH) + 1);" +
153 		"Integer calendarYear = new Integer(cal.get(java.util.Calendar.YEAR));" +
154 		"set" + CharUtil.toUpperCaseAtFisrtChar(TgwNameUtils.PROP_PREFIX_DATEDATE + propertyName) + "(calendarDay);" + 
155 		"set" + CharUtil.toUpperCaseAtFisrtChar(TgwNameUtils.PROP_PREFIX_DATEMONTH + propertyName) + "(calendarMonth);" +
156 		"set" + CharUtil.toUpperCaseAtFisrtChar(TgwNameUtils.PROP_PREFIX_DATEYEAR + propertyName) + "(calendarYear);" +
157 		"}";		
158 	}
159 	
160 	private static final Map buildDatePropertyMap(Class srcClass, List dateClassPropertyList){
161 		Map propertyMap = new HashMap();
162 		for(Iterator i = dateClassPropertyList.iterator(); i.hasNext();){
163 			PropertyDescriptor desc = (PropertyDescriptor) i.next();
164 			String propertyName = desc.getName();
165 			String[] dateProperties = TgwNameUtils.toDateParts(propertyName);
166 			
167 			for(int j=0;j<dateProperties.length;j++){
168 				String dateProp = dateProperties[j];
169 				try{
170 					new PropertyDescriptor(dateProp,srcClass);
171 				}catch(IntrospectionException ise){
172 					propertyMap.put(dateProp,"java.lang.Integer");
173 				}
174 			}			
175 		}
176 		return propertyMap;
177 	}
178 		
179 }