Package org.hibernate.tool.ide.completion

Source Code of org.hibernate.tool.ide.completion.ConfigurationCompletion

package org.hibernate.tool.ide.completion;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;
import org.hibernate.tool.hbm2x.Cfg2JavaTool;
import org.hibernate.tool.hbm2x.pojo.EntityPOJOClass;

/**
* Completion based on a Configuration.
* package protected for now - not meant to be used externally.
*
* @author Max Rydahl Andersen
*
*/
class ConfigurationCompletion {

  private final Configuration cfg;

  public ConfigurationCompletion(Configuration cfg) {
    this.cfg = cfg;
   
  }

  public void getMatchingImports(String prefix , IHQLCompletionRequestor collector) {
    getMatchingImports( prefix, prefix.length() , collector );
  }
 
  public void getMatchingImports(String prefix, int cursorPosition, IHQLCompletionRequestor collector) {
    Iterator iterator = cfg.getImports().entrySet().iterator();
    while ( iterator.hasNext() ) {
      Map.Entry entry = (Entry) iterator.next();
      String entityImport = (String) entry.getKey();
      String entityName = (String) entry.getValue();
     
      if(entityImport.toLowerCase().startsWith(prefix.toLowerCase())) {
        HQLCompletionProposal proposal = createStartWithCompletionProposal( prefix, cursorPosition, HQLCompletionProposal.ENTITY_NAME, entityImport );
        proposal.setShortEntityName( entityImport );
        proposal.setEntityName( entityName );
        collector.accept(proposal);       
               
      }
    }   
  }
 
  public void getMatchingKeywords(String prefix, int cursorPosition, IHQLCompletionRequestor collector) {
    findMatchingWords( cursorPosition, prefix, HQLAnalyzer.getHQLKeywords(), HQLCompletionProposal.KEYWORD, collector);
  }

  public void getMatchingFunctions(String prefix, int cursorPosition, IHQLCompletionRequestor collector) {
    findMatchingWords( cursorPosition, prefix, HQLAnalyzer.getHQLFunctionNames(), HQLCompletionProposal.FUNCTION, collector);
  }
 
  public void getMatchingProperties(String path, String prefix, IHQLCompletionRequestor hcc) {
    getMatchingProperties( path, prefix, prefix.length(), hcc );
  }
 
  public void getMatchingProperties(String path, String prefix, int cursorPosition, IHQLCompletionRequestor hcc) {
    int idx = path.indexOf('/');
        if (idx == -1) { // root name
            PersistentClass cmd = getPersistentClass(path);
            if (cmd == null) {
                return;
            }
            addPropertiesToList(cmd, prefix, cursorPosition, hcc);           
        } else {
            String baseEntityName = path.substring(0, idx);
            String propertyPath = path.substring(idx + 1);
            Value value = getNextAttributeType(baseEntityName, propertyPath);
            if (value == null) {
                return;
            }
           
            // Go to the next property (get the y of x/y/z when root is x)
            idx = propertyPath.indexOf('/');
            if (idx == -1) {
                path = "";
            } else {
                path = propertyPath.substring(idx + 1);
            }
            if (path.length() == 0) {
                // No properties left
                if (value instanceof Component) {
                    addPropertiesToList((Component) value, prefix, cursorPosition, hcc);
                } else if (value instanceof Collection && ((Collection)value).getElement() instanceof Component) {
                  addPropertiesToList((Component) ((Collection)value).getElement(), prefix, cursorPosition, hcc);
                } else {
                   addPropertiesToList(getPersistentClass( getReferencedEntityName( value ) ), prefix, cursorPosition, hcc);
                }
            } else {
                // Nested properties
                if (value instanceof Component) {
                    // We need to find the first non-component type
                    while (value instanceof Component && path.length() > 0) {
                        value = getNextAttributeType((Component) value, path);
                        if (value != null) {
                            // Consume part of the canonical path
                            idx = path.indexOf('/');
                            if (idx != -1) {
                                path = path.substring(idx + 1);
                            } else {
                                path = "";
                            }
                        }
                    }
                    if (value instanceof Component) {
                        addPropertiesToList((Component) value, prefix, cursorPosition, hcc);
                    } else if (value != null) {
                        if (path.length() > 0) {
                            path = getReferencedEntityName( value ) + "/" + path;
                        } else {
                            path = getReferencedEntityName( value );
                        }
                        getMatchingProperties( path, prefix, cursorPosition, hcc );
                    }
                } else {
                    // Just call the method recursively to add our new type
                    getMatchingProperties(getReferencedEntityName( value ) + "/" + path, prefix, cursorPosition, hcc);
                }
            }
        }
  }

  private String getReferencedEntityName(Value value) {
    if(value instanceof ToOne) {
      return ((ToOne)value).getReferencedEntityName();
    }
    if ( value instanceof Collection ) {
      Collection collection = ((Collection)value);
      Value element = collection.getElement();
      String elementType = getReferencedEntityName( element );
      if(collection.isIndexed()) {
        //TODO..list/map
        /*IndexedCollection idxCol = (IndexedCollection) collection;
        if(!idxCol.isList()) {
          Value idxElement = idxCol.getIndex();
          String indexType = getReferencedEntityName( value );
          genericDecl = indexType + "," + elementType;
        }*/
      }      
      return elementType;
    }
   
    if(value instanceof OneToMany) {
      return ((OneToMany)value).getReferencedEntityName();
    }
   
    return null;
  }

  private void addPropertiesToList(PersistentClass cmd, String prefix, int cursorPosition, IHQLCompletionRequestor hcc) {
    if (cmd == null) {
            return;
        }
        if (prefix == null) {
            prefix = "";
        }
       
        // Add superclass's properties too
        while (cmd != null){
          EntityPOJOClass pc = new EntityPOJOClass(cmd, new Cfg2JavaTool()); // TODO: we should extract the needed functionallity from this hbm2java class.
           
          Iterator allPropertiesIterator = pc.getAllPropertiesIterator();
            while ( allPropertiesIterator.hasNext() ) {
          Property property = (Property) allPropertiesIterator.next();
          String candidate = property.getName();
            if (prefix.length() == 0 || candidate.toLowerCase().startsWith(prefix.toLowerCase())) {
              HQLCompletionProposal proposal = createStartWithCompletionProposal( prefix, cursorPosition, HQLCompletionProposal.PROPERTY, candidate );
              proposal.setEntityName( cmd.getEntityName() );
              proposal.setProperty( property );
              proposal.setPropertyName( candidate );         
            hcc.accept( proposal);                         
                }
            }
            cmd = cmd.getSuperclass();
        }
            
  }

  private HQLCompletionProposal createStartWithCompletionProposal(String prefix, int cursorPosition, int kind, String candidate) {
    HQLCompletionProposal proposal = new HQLCompletionProposal(kind, cursorPosition);
    if(candidate.startsWith(prefix)) {
      proposal.setCompletion( candidate.substring(prefix.length()) );
      proposal.setSimpleName( candidate );
      proposal.setReplaceStart( cursorPosition )
      proposal.setReplaceEnd( cursorPosition );
    } else {
      proposal.setCompletion( candidate );
      proposal.setSimpleName( candidate );
      proposal.setReplaceStart( cursorPosition  - prefix.length() );// replace prefix 
      proposal.setReplaceEnd( cursorPosition );  
    }
    return proposal;
  }

  /** returns PersistentClass for path. Can be null if path is an imported non-mapped class */
  private PersistentClass getPersistentClass(String path) {
    if(path==null) return null;
    String entityName = (String) cfg.getImports().get( path );
    if(entityName==null) {
      return cfg.getClassMapping( path ); // annotationconfiguration does not put full imports into imports.
    } else {
      return cfg.getClassMapping( entityName );
   
  }

  public String getCanonicalPath(List qts, String name) {
    Map alias2Type = new HashMap();
        for (Iterator iter = qts.iterator(); iter.hasNext();) {
      EntityNameReference qt = (EntityNameReference) iter.next();
            alias2Type.put(qt.getAlias(), qt.getEntityName());
        }
        if (qts.size() == 1) {
            EntityNameReference visible = (EntityNameReference) qts.get(0);
            String alias = visible.getAlias();
            if (name.equals(alias)) {
                return visible.getEntityName();
            } else if (alias == null || alias.length() == 0 || alias.equals(visible.getEntityName())) {
                return visible.getEntityName() + "/" + name;
            }
        }
        return getCanonicalPath(new HashSet(), alias2Type, name);   
  }
 
  private String getCanonicalPath(Set resolved, Map alias2Type, String name) {
        if (resolved.contains(name)) {
            // To prevent a stack overflow
            return name;
        }
        resolved.add(name);
        String type = (String) alias2Type.get(name);
        if (type != null) {
            return name.equals(type) ? name : getCanonicalPath(resolved, alias2Type, type);
        }
        int idx = name.lastIndexOf('.');
        if (idx == -1) {
            return type != null ? type : name;
        }
        String baseName = name.substring(0, idx);
        String prop = name.substring(idx + 1);
        if (isAliasKnown(alias2Type, baseName)) {
            return getCanonicalPath(resolved, alias2Type, baseName) + "/" + prop;
        } else {
            return name;
        }
    }
 
  private static boolean isAliasKnown(Map alias2Type, String alias) {
        if (alias2Type.containsKey(alias)) {
            return true;
        }
        int idx = alias.lastIndexOf('.');
        if (idx == -1) {
            return false;
        }
        return isAliasKnown(alias2Type, alias.substring(0, idx));
    }
   
  private Value getNextAttributeType(String type, String attributePath) {
        PersistentClass cmd = getPersistentClass( type );
        if (cmd == null) {
            return null;
        }
        String attribute;
        int idx = attributePath.indexOf('/');
        if (idx == -1) {
            attribute = attributePath;
        } else {
            attribute = attributePath.substring(0, idx);
        }
       
        String idName = cmd.getIdentifierProperty()==null?null:cmd.getIdentifierProperty().getName();
        if (attribute.equals(idName)) {
            return cmd.getIdentifierProperty().getValue();
        }
        try {
          Property property = cmd.getProperty( attribute );
          return property==null?null:property.getValue();
        } catch (HibernateException he) {
          return null;
        }
               
    }

  private Value getNextAttributeType(Component t, String attributeName) {
        int idx = attributeName.indexOf('/');
        if (idx != -1) {
            attributeName = attributeName.substring(0, idx);
        }
        Iterator names = t.getPropertyIterator();
        int i = 0;
        while ( names.hasNext() ) {
      Property element = (Property) names.next();
      String name = element.getName();
      if (attributeName.equals(name)) {
                return element.getValue();
            }
            i++;
        }
        return null;
    }
 
  void addPropertiesToList(Component t, String prefix, int cursorPosition, IHQLCompletionRequestor hcc) {
        if (t == null) {
            return;
        }
        Iterator props = t.getPropertyIterator();
        int i = 0;
        while ( props.hasNext() ) {
      Property element = (Property) props.next();     
      String candidate = element.getName();
      if (candidate.toLowerCase().startsWith(prefix.toLowerCase())) {
        HQLCompletionProposal proposal = createStartWithCompletionProposal( prefix, cursorPosition, HQLCompletionProposal.PROPERTY, candidate );
        //proposal.setEntityName( cmd.getEntityName() ); ...we don't know here..TODO: pass in the "path"
          proposal.setPropertyName( candidate );
          proposal.setProperty(element);
        hcc.accept( proposal);                      
            }
            i++;
        }
    }
 
  private void findMatchingWords(int cursorPosition, String prefix, String[] words, int kind, IHQLCompletionRequestor hcc) {
    int i = Arrays.binarySearch(words, prefix.toLowerCase());
    if(i<0) {
      i = Math.abs(i+1);
    }
   
    for (int cnt = i; cnt < words.length; cnt++) {
      String word = words[cnt];
      if(word.toLowerCase().startsWith(prefix.toLowerCase())) {
        HQLCompletionProposal proposal = createStartWithCompletionProposal( prefix, cursorPosition, kind, word );
        hcc.accept( proposal);       
      } else {
        break;
      }
    }
  }

}
TOP

Related Classes of org.hibernate.tool.ide.completion.ConfigurationCompletion

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.