001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.devtools.generators.jpa;
017
018import org.kuali.rice.krad.bo.PersistableBusinessObject;
019import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
020
021import javax.persistence.AttributeOverride;
022import javax.persistence.AttributeOverrides;
023import javax.persistence.Column;
024import javax.persistence.Id;
025import javax.persistence.JoinColumn;
026import javax.persistence.JoinColumns;
027import javax.persistence.ManyToOne;
028import javax.persistence.OneToMany;
029import javax.persistence.OneToOne;
030import javax.persistence.Table;
031import java.lang.reflect.Field;
032import java.util.ArrayList;
033import java.util.HashMap;
034import java.util.List;
035import java.util.Map;
036
037/**
038 * This is a description of what this class does - kellerj don't forget to fill this in. 
039 * 
040 * @author Kuali Rice Team (rice.collab@kuali.org)
041 *
042 */
043public class JpaToOjbMetadata {
044
045        public static void main( String[] args ) throws ClassNotFoundException {
046                
047                Class<? extends PersistableBusinessObjectBase> clazz =
048                (Class<? extends PersistableBusinessObjectBase>) Class.forName(args[0]);
049
050                
051                StringBuffer sb = new StringBuffer( 1000 );
052                Table tableAnnotation = (Table)clazz.getAnnotation( Table.class );
053                
054                sb.append( "    <class-descriptor class=\"" ).append( clazz.getName() ).append( "\" table=\"" );
055                sb.append( tableAnnotation.name() ).append( "\">\r\n" );
056
057                getClassFields( clazz, sb, null );
058                getReferences( clazz, sb );
059                sb.append( "    </class-descriptor>\r\n" );
060                
061                System.out.println( sb.toString() );
062        }
063
064        
065        private static String javaToOjbDataType( Class<? extends Object> dataType ) {
066                if ( dataType.equals( String.class ) ) {
067                        return "VARCHAR";
068                } else if (dataType.equals(Long.class) || dataType.equals(Integer.class)) {
069                        return "BIGINT";
070                } else if (dataType.equals(java.util.Date.class) || dataType.equals(java.sql.Date.class)) {
071                        return "DATE";
072                } else if (dataType.equals(java.sql.Timestamp.class)) {
073                        return "TIMESTAMP";
074                }
075                return "VARCHAR";
076        }
077        
078        private static void getClassFields( Class<? extends Object> clazz, StringBuffer sb, Map<String,AttributeOverride> overrides ) {
079                // first get annotation overrides
080                if ( overrides == null ) {
081                        overrides = new HashMap<String,AttributeOverride>();
082                }
083                if ( clazz.getAnnotation( AttributeOverride.class ) != null ) {
084                        AttributeOverride ao = (AttributeOverride)clazz.getAnnotation( AttributeOverride.class );
085                        if ( !overrides.containsKey(ao.name() ) ) {
086                                overrides.put(ao.name(), ao);
087                        }
088                }
089                if ( clazz.getAnnotation( AttributeOverrides.class ) != null ) {
090                        for ( AttributeOverride ao : ((AttributeOverrides)clazz.getAnnotation( AttributeOverrides.class )).value() ) {
091                                if ( !overrides.containsKey(ao.name() ) ) {
092                                        overrides.put(ao.name(), ao);
093                                }
094                                overrides.put(ao.name(),ao);
095                        }
096                }
097                for ( Field field : clazz.getDeclaredFields() ) {
098                        Id id = (Id)field.getAnnotation( Id.class );
099                        Column column = (Column)field.getAnnotation( Column.class );
100                        if ( column != null ) {
101                                sb.append( "            <field-descriptor name=\"" );
102                                sb.append( field.getName() );
103                                sb.append( "\" column=\"" );
104                                if ( overrides.containsKey(field.getName() ) ) {
105                                        sb.append( overrides.get(field.getName()).column().name() );
106                                } else {
107                                        sb.append( column.name() );
108                                }
109                                sb.append( "\" jdbc-type=\"" );
110                                sb.append( javaToOjbDataType( field.getType() ) );
111                                sb.append( "\" " );
112                                if ( id != null ) {
113                                        sb.append( "primarykey=\"true\" " );
114                                }
115                                if ( field.getName().equals( "objectId" ) ) {
116                                        sb.append( "index=\"true\" " );
117                                }
118                                if ( field.getType() == boolean.class ) {
119                                        sb.append( "conversion=\"org.kuali.rice.krad.util.OjbCharBooleanConversion3\" " );
120                                }
121                                if ( field.getName().equals( "versionNumber" ) ) {
122                                        sb.append( "locking=\"true\" " );
123                                }
124                                sb.append( "/>\r\n" );
125                        }
126                }
127                if ( !clazz.equals( PersistableBusinessObject.class ) && clazz.getSuperclass() != null ) {
128                        getClassFields( clazz.getSuperclass(), sb, overrides );
129                }
130        }
131
132        private static void getReferences( Class<? extends Object> clazz, StringBuffer sb ) {
133                for ( Field field : clazz.getDeclaredFields() ) {
134                        JoinColumns multiKey = (JoinColumns)field.getAnnotation( JoinColumns.class );
135                        JoinColumn singleKey = (JoinColumn)field.getAnnotation( JoinColumn.class );
136                        if ( multiKey != null || singleKey != null ) {
137                                List<JoinColumn> keys = new ArrayList<JoinColumn>();
138                                if ( singleKey != null ) {
139                                        keys.add( singleKey );
140                                }
141                                if ( multiKey != null ) {
142                                        for ( JoinColumn col : multiKey.value() ) {
143                                                keys.add( col );
144                                        }
145                                }
146                                OneToOne oneToOne = field.getAnnotation( OneToOne.class );
147                                if ( oneToOne != null ) {
148                                        sb.append( "            <reference-descriptor name=\"" );
149                                        sb.append( field.getName() );
150                                        sb.append( "\" class-ref=\"" );
151                                        if ( !oneToOne.targetEntity().getName().equals( "void" ) ) {
152                                                sb.append( oneToOne.targetEntity().getName() );
153                                        } else {
154                                                sb.append( field.getType().getName() );
155                                        }
156                                        sb.append( "\" auto-retrieve=\"true\" auto-update=\"none\" auto-delete=\"none\" proxy=\"true\">\r\n" );
157                                        for ( JoinColumn col : keys ) {
158                                                sb.append( "                    <foreignkey field-ref=\"" );
159                                                sb.append( getPropertyFromField( clazz, col.name() ) );
160                                                sb.append( "\" />\r\n" );
161                                        }
162                                        sb.append( "            </reference-descriptor>\r\n" );
163                                }
164                                ManyToOne manyToOne = field.getAnnotation( ManyToOne.class );
165                                if ( manyToOne != null ) {
166                                        sb.append( "            <reference-descriptor name=\"" );
167                                        sb.append( field.getName() );
168                                        sb.append( "\" class-ref=\"" );
169                                        if ( !manyToOne.targetEntity().getName().equals( "void" ) ) {
170                                                sb.append( manyToOne.targetEntity().getName() );
171                                        } else {
172                                                sb.append( field.getType().getName() );
173                                        }
174                                        sb.append( "\" auto-retrieve=\"true\" auto-update=\"none\" auto-delete=\"none\" proxy=\"true\">\r\n" );
175                                        for ( JoinColumn col : keys ) {
176                                                sb.append( "                    <foreignkey field-ref=\"" );
177                                                sb.append( getPropertyFromField( clazz, col.name() ) );
178                                                sb.append( "\" />\r\n" );
179                                        }
180                                        sb.append( "            </reference-descriptor>\r\n" );
181                                }
182                                OneToMany oneToMany = field.getAnnotation( OneToMany.class );
183                                if ( oneToMany != null ) {
184                                        sb.append( "            <collection-descriptor name=\"" );
185                                        sb.append( field.getName() );
186                                        sb.append( "\" element-class-ref=\"" );
187                                        sb.append( oneToMany.targetEntity().getName() );
188                                        sb.append( "\" collection-class=\"org.apache.ojb.broker.util.collections.ManageableArrayList\" auto-retrieve=\"true\" auto-update=\"object\" auto-delete=\"object\" proxy=\"true\">\r\n" );
189                                        for ( JoinColumn col : keys ) {
190                                                sb.append( "                    <inverse-foreignkey field-ref=\"" );
191                                                sb.append( getPropertyFromField( clazz, col.name() ) );
192                                                sb.append( "\" />\r\n" );
193                                        }
194                                        sb.append( "            </collection-descriptor>\r\n" );
195                                }
196                        }
197                }
198        }
199        
200        private static String getPropertyFromField( Class<? extends Object> clazz, String colName ) {
201                for ( Field field : clazz.getDeclaredFields() ) {
202                        Column column = (Column)field.getAnnotation( Column.class );
203                        if ( column != null ) {
204                                if ( column.name().equals( colName ) ) {
205                                        return field.getName();
206                                }
207                        }
208                }
209                return "";
210        }
211}