View Javadoc

1   /**
2    * Copyright 2005-2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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.kuali.rice.devtools.generators.jpa;
17  
18  import org.kuali.rice.krad.bo.PersistableBusinessObject;
19  import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
20  
21  import javax.persistence.AttributeOverride;
22  import javax.persistence.AttributeOverrides;
23  import javax.persistence.Column;
24  import javax.persistence.Id;
25  import javax.persistence.JoinColumn;
26  import javax.persistence.JoinColumns;
27  import javax.persistence.OneToMany;
28  import javax.persistence.Table;
29  import java.lang.reflect.Field;
30  import java.util.ArrayList;
31  import java.util.HashMap;
32  import java.util.List;
33  import java.util.Map;
34  
35  /**
36   * This is a description of what this class does - kellerj don't forget to fill this in. 
37   * 
38   * @author Kuali Rice Team (rice.collab@kuali.org)
39   *
40   */
41  public class JpaToDdl {
42  
43  	public static void main( String[] args ) throws ClassNotFoundException {
44  		
45  		Class<? extends PersistableBusinessObjectBase> clazz =
46                  (Class<? extends PersistableBusinessObjectBase>) Class.forName(args[0]);
47  
48  		
49  		StringBuffer sb = new StringBuffer( 1000 );
50  		StringBuffer pk = new  StringBuffer();
51  		Table tableAnnotation = (Table)clazz.getAnnotation( Table.class );
52  		
53  		sb.append( "CREATE TABLE " ).append( tableAnnotation.name().toLowerCase() ).append( " (\r\n" );
54  
55  		getClassFields( tableAnnotation.name().toLowerCase(), clazz, sb, pk, null );
56  		pk.append( " )\r\n" );
57  		sb.append( pk );
58  		sb.append( ")\r\n" );
59  		sb.append( "/\r\n" );
60  		System.out.println( sb.toString() );
61  		sb.setLength( 0 );
62  		getReferences( clazz, sb );
63  		System.out.println( sb.toString() );
64  	}
65  
66  	
67  	private static String javaToSqlDataType( Class<? extends Object> dataType ) {
68  		if ( dataType.equals( String.class ) ) {
69  			return "VARCHAR(40)";
70  		} else if (dataType.equals(Long.class) || dataType.equals(Integer.class)) {
71  			return "NUMBER(?,?)";
72  		} else if (dataType.equals(java.util.Date.class) || dataType.equals(java.sql.Date.class)) {
73  			return "DATE";
74  		} else if (dataType.equals(java.sql.Timestamp.class)) {
75  			return "TIMESTAMP";
76  		}
77  		return "VARCHAR(40)";
78  	}
79  	
80  	private static void getClassFields( String tableName, Class<? extends Object> clazz, StringBuffer sb, StringBuffer pk, Map<String,AttributeOverride> overrides ) {
81  		// first get annotation overrides
82  		if ( overrides == null ) {
83  			overrides = new HashMap<String,AttributeOverride>();
84  		}
85  		if ( clazz.getAnnotation( AttributeOverride.class ) != null ) {
86  			AttributeOverride ao = (AttributeOverride)clazz.getAnnotation( AttributeOverride.class );
87  			if ( !overrides.containsKey(ao.name() ) ) {
88  				overrides.put(ao.name(), ao);
89  			}
90  		}
91  		if ( clazz.getAnnotation( AttributeOverrides.class ) != null ) {
92  			for ( AttributeOverride ao : ((AttributeOverrides)clazz.getAnnotation( AttributeOverrides.class )).value() ) {
93  				if ( !overrides.containsKey(ao.name() ) ) {
94  					overrides.put(ao.name(), ao);
95  				}
96  				overrides.put(ao.name(),ao);
97  			}
98  		}
99  		for ( Field field : clazz.getDeclaredFields() ) {
100 			Id id = (Id)field.getAnnotation( Id.class );
101 			Column column = (Column)field.getAnnotation( Column.class );
102 			if ( column != null ) {
103 				sb.append( "\t" );
104 				if ( field.getName().equals( "objectId" ) ) {
105 					sb.append( "obj_id\t\tVARCHAR2(36) NOT NULL" );
106 				} else if ( field.getName().equals( "versionNumber" ) ) {
107 					sb.append( "ver_nbr\t\tNUMBER(8,0)" );
108 				} else {
109 					if ( overrides.containsKey(field.getName() ) ) {
110 						sb.append( overrides.get(field.getName()).column().name().toLowerCase() );
111 					} else {
112 						sb.append( column.name().toLowerCase() );
113 					}
114 					sb.append( "\t\t" );
115 					if ( field.getType() == boolean.class ) {
116 						sb.append( "VARCHAR2(1) DEFAULT 'Y'" );
117 					} else {
118 						sb.append( javaToSqlDataType( field.getType() ) );
119 					}
120 					if ( id != null ) {
121 						if ( pk.length() == 0 ) {
122 							pk.append( "\tCONSTRAINT " + tableName + "p1 PRIMARY KEY ( " );
123 						} else {
124 							pk.append( ", " );
125 						}
126 						if ( overrides.containsKey(field.getName() ) ) {
127 							pk.append( overrides.get(field.getName()).column().name().toLowerCase() );
128 						} else {
129 							pk.append( column.name().toLowerCase() );
130 						}
131 					}
132 				}
133 				sb.append( ",\r\n" );
134 			}
135 		}
136 		if ( !clazz.equals( PersistableBusinessObject.class ) && clazz.getSuperclass() != null ) {
137 			getClassFields( tableName, clazz.getSuperclass(), sb, pk, overrides );
138 		}
139 	}
140 
141 	private static void getReferences( Class<? extends Object> clazz, StringBuffer sb ) {
142 		for ( Field field : clazz.getDeclaredFields() ) {
143 			JoinColumns multiKey = (JoinColumns)field.getAnnotation( JoinColumns.class );
144 			JoinColumn singleKey = (JoinColumn)field.getAnnotation( JoinColumn.class );
145 			if ( multiKey != null || singleKey != null ) {
146 				List<JoinColumn> keys = new ArrayList<JoinColumn>();
147 				if ( singleKey != null ) {
148 					keys.add( singleKey );
149 				}
150 				if ( multiKey != null ) {
151 					for ( JoinColumn col : multiKey.value() ) {
152 						keys.add( col );
153 					}
154 				}
155 				OneToMany oneToMany = field.getAnnotation( OneToMany.class );
156 				if ( oneToMany != null ) {
157 					sb.append( "ALTER TABLE " );
158 					sb.append( field.getName() );
159 					sb.append( "\" element-class-ref=\"" );
160 					sb.append( oneToMany.targetEntity().getName() );
161 					sb.append( "\" collection-class=\"org.apache.ojb.broker.util.collections.ManageableArrayList\" auto-retrieve=\"true\" auto-update=\"object\" auto-delete=\"object\" proxy=\"true\">\r\n" );
162 					for ( JoinColumn col : keys ) {
163 						sb.append( "			<inverse-foreignkey field-ref=\"" );
164 						sb.append( getPropertyFromField( clazz, col.name() ) );
165 						sb.append( "\" />\r\n" );
166 					}
167 					sb.append( "		</collection-descriptor>\r\n" );
168 				}
169 			}
170 		}
171 	}
172 	
173 	private static String getPropertyFromField( Class<? extends Object> clazz, String colName ) {
174 		for ( Field field : clazz.getDeclaredFields() ) {
175 			Column column = (Column)field.getAnnotation( Column.class );
176 			if ( column != null ) {
177 				if ( column.name().equals( colName ) ) {
178 					return field.getName();
179 				}
180 			}
181 		}
182 		return "";
183 	}
184 }