001 /** 002 * Copyright 2005-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.devtools.generators.jpa; 017 018 import org.kuali.rice.krad.bo.PersistableBusinessObject; 019 import org.kuali.rice.krad.bo.PersistableBusinessObjectBase; 020 021 import javax.persistence.AttributeOverride; 022 import javax.persistence.AttributeOverrides; 023 import javax.persistence.Column; 024 import javax.persistence.Id; 025 import javax.persistence.JoinColumn; 026 import javax.persistence.JoinColumns; 027 import javax.persistence.OneToMany; 028 import javax.persistence.Table; 029 import java.lang.reflect.Field; 030 import java.util.ArrayList; 031 import java.util.HashMap; 032 import java.util.List; 033 import java.util.Map; 034 035 /** 036 * This is a description of what this class does - kellerj don't forget to fill this in. 037 * 038 * @author Kuali Rice Team (rice.collab@kuali.org) 039 * 040 */ 041 public class JpaToDdl { 042 043 public static void main( String[] args ) throws ClassNotFoundException { 044 045 Class<? extends PersistableBusinessObjectBase> clazz = 046 (Class<? extends PersistableBusinessObjectBase>) Class.forName(args[0]); 047 048 049 StringBuffer sb = new StringBuffer( 1000 ); 050 StringBuffer pk = new StringBuffer(); 051 Table tableAnnotation = (Table)clazz.getAnnotation( Table.class ); 052 053 sb.append( "CREATE TABLE " ).append( tableAnnotation.name().toLowerCase() ).append( " (\r\n" ); 054 055 getClassFields( tableAnnotation.name().toLowerCase(), clazz, sb, pk, null ); 056 pk.append( " )\r\n" ); 057 sb.append( pk ); 058 sb.append( ")\r\n" ); 059 sb.append( "/\r\n" ); 060 System.out.println( sb.toString() ); 061 sb.setLength( 0 ); 062 getReferences( clazz, sb ); 063 System.out.println( sb.toString() ); 064 } 065 066 067 private static String javaToSqlDataType( Class<? extends Object> dataType ) { 068 if ( dataType.equals( String.class ) ) { 069 return "VARCHAR(40)"; 070 } else if (dataType.equals(Long.class) || dataType.equals(Integer.class)) { 071 return "NUMBER(?,?)"; 072 } else if (dataType.equals(java.util.Date.class) || dataType.equals(java.sql.Date.class)) { 073 return "DATE"; 074 } else if (dataType.equals(java.sql.Timestamp.class)) { 075 return "TIMESTAMP"; 076 } 077 return "VARCHAR(40)"; 078 } 079 080 private static void getClassFields( String tableName, Class<? extends Object> clazz, StringBuffer sb, StringBuffer pk, Map<String,AttributeOverride> overrides ) { 081 // first get annotation overrides 082 if ( overrides == null ) { 083 overrides = new HashMap<String,AttributeOverride>(); 084 } 085 if ( clazz.getAnnotation( AttributeOverride.class ) != null ) { 086 AttributeOverride ao = (AttributeOverride)clazz.getAnnotation( AttributeOverride.class ); 087 if ( !overrides.containsKey(ao.name() ) ) { 088 overrides.put(ao.name(), ao); 089 } 090 } 091 if ( clazz.getAnnotation( AttributeOverrides.class ) != null ) { 092 for ( AttributeOverride ao : ((AttributeOverrides)clazz.getAnnotation( AttributeOverrides.class )).value() ) { 093 if ( !overrides.containsKey(ao.name() ) ) { 094 overrides.put(ao.name(), ao); 095 } 096 overrides.put(ao.name(),ao); 097 } 098 } 099 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 }