1 19 package org.apache.cayenne.access.jdbc; 20 21 import java.util.Iterator ; 22 23 import org.apache.cayenne.ejbql.EJBQLBaseVisitor; 24 import org.apache.cayenne.ejbql.EJBQLException; 25 import org.apache.cayenne.ejbql.EJBQLExpression; 26 import org.apache.cayenne.ejbql.parser.EJBQLFromItem; 27 import org.apache.cayenne.ejbql.parser.EJBQLJoin; 28 import org.apache.cayenne.map.DbJoin; 29 import org.apache.cayenne.map.DbRelationship; 30 import org.apache.cayenne.map.ObjRelationship; 31 import org.apache.cayenne.reflect.ClassDescriptor; 32 33 37 class EJBQLFromTranslator extends EJBQLBaseVisitor { 38 39 private EJBQLTranslationContext context; 40 private String lastId; 41 42 static String makeJoinTailMarker(String id) { 43 return "FROM_TAIL" + id; 44 } 45 46 EJBQLFromTranslator(EJBQLTranslationContext context) { 47 super(true); 48 this.context = context; 49 } 50 51 public boolean visitFrom(EJBQLExpression expression, int finishedChildIndex) { 52 if (finishedChildIndex + 1 == expression.getChildrenCount()) { 53 if (lastId != null) { 54 context.markCurrentPosition(makeJoinTailMarker(lastId)); 55 } 56 } 57 58 return true; 59 } 60 61 public boolean visitFromItem(EJBQLFromItem expression) { 62 63 String id = expression.getId(); 64 65 if (lastId != null) { 66 context.append(','); 67 context.markCurrentPosition(makeJoinTailMarker(lastId)); 68 } 69 70 this.lastId = id; 71 appendTable(id); 72 return false; 73 } 74 75 public boolean visitInnerFetchJoin(EJBQLJoin join) { 76 return visitInnerJoin(join); 78 } 79 80 public boolean visitInnerJoin(EJBQLJoin join) { 81 appendJoin(join, "INNER JOIN"); 82 return false; 83 } 84 85 public boolean visitOuterFetchJoin(EJBQLJoin join) { 86 return visitOuterJoin(join); 88 } 89 90 public boolean visitOuterJoin(EJBQLJoin join) { 91 appendJoin(join, "LEFT OUTER JOIN"); 92 return false; 93 } 94 95 private void appendJoin(EJBQLJoin join, String semantics) { 96 97 String rhsId = join.getRightHandSideId(); 98 99 ObjRelationship joinRelationship = context 100 .getCompiledExpression() 101 .getIncomingRelationship(rhsId); 102 if (joinRelationship == null) { 103 throw new EJBQLException("No join configured for id " + rhsId); 104 } 105 106 DbRelationship incomingDB = (DbRelationship) joinRelationship 108 .getDbRelationships() 109 .get(0); 110 111 String lhsId = join.getLeftHandSideId(); 112 String sourceAlias = context.getTableAlias(lhsId, incomingDB 113 .getSourceEntity() 114 .getName()); 115 116 context.append(" ").append(semantics); 117 String targetAlias = appendTable(rhsId); 118 context.append(" ON ("); 119 120 Iterator it = incomingDB.getJoins().iterator(); 121 if (it.hasNext()) { 122 DbJoin dbJoin = (DbJoin) it.next(); 123 context 124 .append(sourceAlias) 125 .append('.') 126 .append(dbJoin.getSourceName()) 127 .append(" = ") 128 .append(targetAlias) 129 .append('.') 130 .append(dbJoin.getTargetName()); 131 } 132 133 while (it.hasNext()) { 134 context.append(", "); 135 DbJoin dbJoin = (DbJoin) it.next(); 136 context 137 .append(sourceAlias) 138 .append('.') 139 .append(dbJoin.getSourceName()) 140 .append(" = ") 141 .append(targetAlias) 142 .append('.') 143 .append(dbJoin.getTargetName()); 144 } 145 146 context.append(")"); 147 } 148 149 private String appendTable(String id) { 150 ClassDescriptor descriptor = context.getCompiledExpression().getEntityDescriptor( 151 id); 152 153 String tableName = descriptor.getEntity().getDbEntity().getFullyQualifiedName(); 154 String alias = context.getTableAlias(id, tableName); 155 156 context.append(' ').append(tableName).append(' ').append(alias); 159 return alias; 160 } 161 } 162 | Popular Tags |