package ie.corballis.treeway.generate.overrides;

import com.google.common.base.Joiner;
import ie.corballis.treeway.generate.TemplateUtil;
import org.hibernate.cfg.Configuration;
import org.hibernate.mapping.*;
import org.hibernate.tool.hbm2x.Cfg2JavaTool;
import org.hibernate.tool.hbm2x.pojo.EntityPOJOClass;

import java.util.Iterator;

public class CustomEntityPOJOClass extends EntityPOJOClass {

    public CustomEntityPOJOClass(PersistentClass clazz, Cfg2JavaTool cfg) {
        super(clazz, cfg);
    }

    @Override
    public boolean hasFieldInitializor(Property p, boolean useGenerics) {
        return super.getFieldInitialization(p, useGenerics) != null;
    }

    @Override
    public String getGetterSignature(Property p) {
        String signature = super.getGetterSignature(p);
        String[] signatureElements = TemplateUtil.splitByUpperCase(signature);

        if (signatureElements[1].equals("Has")) {
            return signature.replaceAll("^isHas(.*)", "has$1");
        }

        return signature;
    }

    @Override
    public String getImplements() {
        String implementsString = super.getImplements();
        if (implementsString != null && !implementsString.equals("")) {
            return implementsString + ", Persistable<Long>";
        }
        return "Persistable<Long>";
    }

    @Override
    public String generateCollectionAnnotation(Property property, Configuration cfg) {
        StringBuilder annotations = new StringBuilder(super.generateCollectionAnnotation(property, cfg));
        Value value = property.getValue();
        if ( value != null && value instanceof Collection) {
            Collection collection = (Collection) value;
            if ( collection.isInverse() ) {
                PersistentClass pc = null;
                if ( collection.isOneToMany() ) {
                    pc = cfg.getClassMapping( ((OneToMany) collection.getElement()).getReferencedEntityName());
                } else {
                    pc = cfg.getClassMapping( ((ManyToOne) collection.getElement()).getReferencedEntityName());
                }
                Iterator properties = pc.getPropertyClosureIterator();
                while (properties.hasNext() ) {
                    Property manyProperty = (Property) properties.next();
                    MetaAttribute inverseAnnotation = manyProperty.getMetaAttribute("inverse-annotation");
                    if (inverseAnnotation != null) {
                        appendNewAnnotations(annotations, inverseAnnotation);
                    }
                }
            }
        }
        return annotations.toString();
    }

    private void appendNewAnnotations(StringBuilder annotations, MetaAttribute inverseAnnotation) {
        if (annotations.length() > 0) {
            annotations.append("\n");
        }
        annotations.append(Joiner.on("\n").join(inverseAnnotation.getValues()));
    }
}

@@ -172,16 +172,117 @@
 ration;%0A
+import org.hibernate.cfg.JDBCMetaDataConfiguration;%0Aimport org.hibernate.cfg.reveng.TableIdentifier;%0A
 import o
@@ -432,16 +432,38 @@
 terator;
+%0Aimport java.util.Map;
 %0A%0Apublic
@@ -1706,17 +1706,16 @@
     if (
- 
 value !=
@@ -1818,33 +1818,80 @@
             if (
- 
+collection.isOneToMany()) %7B%0A                if (
 collection.isInv
@@ -1896,21 +1896,24 @@
 nverse()
- 
 ) %7B%0A
+    
         
@@ -1942,17 +1942,13 @@
 s pc
- = null;%0A
+;%0A   
     
@@ -1963,13 +1963,13 @@
     
+ 
 if (
- 
 coll
@@ -1988,17 +1988,16 @@
 ToMany()
- 
 ) %7B%0A    
@@ -2004,32 +2004,36 @@
                 
+  
+  
 pc = cfg.getClas
@@ -2041,17 +2041,16 @@
 Mapping(
- 
 ((OneToM
@@ -2123,16 +2123,20 @@
         
+ 
+   
 %7D else %7B
@@ -2136,16 +2136,20 @@
  else %7B%0A
+    
         
@@ -2185,17 +2185,16 @@
 Mapping(
- 
 ((ManyTo
@@ -2259,34 +2259,42 @@
                 
+ 
-%7D%0A
+   %7D%0A    
                 
@@ -2364,16 +2364,20 @@
         
+  
+  
 while (p
@@ -2399,13 +2399,16 @@
 xt()
- 
 ) %7B%0A
+    
     
@@ -2497,16 +2497,20 @@
         
+  
+  
 MetaAttr
@@ -2604,24 +2604,28 @@
             
+    
 if (inverseA
@@ -2669,16 +2669,20 @@
         
+   
+ 
 appendNe
@@ -2727,16 +2727,1047 @@
 ation);%0A
+                        %7D%0A                    %7D%0A                %7D%0A            %7D else %7B%0A                // ManyToMany%0A                Column column = (Column) collection.getKey().getColumnIterator().next();%0A                Table joinTable = column.getValue().getTable();%0A                TableIdentifier tableIdentifier =%0A                    new TableIdentifier(joinTable.getCatalog(), joinTable.getSchema(), joinTable.getName());%0A                Map metaAttributes = ((JDBCMetaDataConfiguration) cfg).getReverseEngineeringStrategy()%0A                                                                      .columnToMetaAttributes(tableIdentifier,%0A                                                                                              column.getName());%0A                if (metaAttributes != null) %7B%0A                    MetaAttribute metaAnnotations = (MetaAttribute) metaAttributes.get(%22annotation%22);%0A                    if (metaAnnotations != null) %7B%0A                        appendNewAnnotations(annotations, metaAnnotations);%0A
         

Support annotation meta attribute for ManyToMany relations