CompiledExpression compile()

in cayenne/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java [87:235]


    CompiledExpression compile(String source, EJBQLExpression parsed) {
        parsed.visit(new CompilationVisitor());

        Map<EJBQLPath, Integer> pathsInSelect = new HashMap<>();

        for (int i = 0; i < parsed.getChildrenCount(); i++) {
            if (parsed.getChild(i) instanceof EJBQLSelectClause) {

                EJBQLExpression parsedTemp = parsed.getChild(i);
                boolean stop = false;

                while (parsedTemp.getChildrenCount() > 0 && !stop) {
                    EJBQLExpression newParsedTemp = null;
                    for (int j = 0; j < parsedTemp.getChildrenCount(); j++) {
                        if (parsedTemp.getChild(j) instanceof EJBQLSelectExpression) {
                            for (int k = 0; k < parsedTemp
                                    .getChild(j)
                                    .getChildrenCount(); k++) {

                                if (parsedTemp.getChild(j).getChild(k) instanceof EJBQLPath) {
                                    pathsInSelect.put((EJBQLPath) parsedTemp
                                            .getChild(j)
                                            .getChild(k), j);

                                }
                            }
                        }
                        else {
                            if (parsedTemp.getChild(j).getChildrenCount() == 0) {
                                stop = true;
                            }
                            else {
                                newParsedTemp = parsedTemp.getChild(j);
                            }
                        }
                    }

                    if (!stop && newParsedTemp != null) {
                        parsedTemp = newParsedTemp;
                    }
                    else {
                        stop = true;
                    }
                }
            }
        }

        // postprocess paths, now that all id vars are resolved
        if (paths != null) {
            for (EJBQLPath path : paths) {
                String id = normalizeIdPath(path.getId());
                ClassDescriptor descriptor = descriptorsById.get(id);
                if (descriptor == null) {
                    throw new EJBQLException("Unmapped id variable: " + id);
                }

                StringBuilder buffer = new StringBuilder(id);

                ObjRelationship incoming = null;
                String pathRelationshipString = "";

                for (int i = 1; i < path.getChildrenCount(); i++) {

                    String pathChunk = path.getChild(i).getText();
                    if(pathChunk.endsWith(Entity.OUTER_JOIN_INDICATOR)) {
                    	pathChunk = pathChunk.substring(0, pathChunk.length() - 1);
                    }
                    
                    buffer.append('.').append(pathChunk);

                    PropertyDescriptor property = descriptor.getProperty(pathChunk);

                    if (property instanceof ArcProperty) {
                        incoming = ((ArcProperty) property).getRelationship();
                        descriptor = ((ArcProperty) property).getTargetDescriptor();
                        pathRelationshipString = buffer.substring(0, buffer.length());

                        descriptorsById.put(pathRelationshipString, descriptor);
                        incomingById.put(pathRelationshipString, incoming);

                    }
                }

                if (pathsInSelect.size() > 0
                        && incoming != null
                        && pathRelationshipString.length() > 0
                        && pathRelationshipString.equals(buffer.toString())) {

                    EJBQLIdentifier ident = new EJBQLIdentifier(0);
                    ident.text = pathRelationshipString;

                    Integer integer = pathsInSelect.get(path);
                    if (integer != null) {
                        resultComponents.remove(integer.intValue());
                        resultComponents.add(integer, ident);
                        rootId = pathRelationshipString;
                    }
                }
            }
        }

        CompiledExpression compiled = new CompiledExpression();
        compiled.setExpression(parsed);
        compiled.setSource(source);

        compiled.setRootId(rootId);
        compiled.setDescriptorsById(descriptorsById);
        compiled.setIncomingById(incomingById);
        compiled.setPrefetchTree(prefetchTree);

        if (resultComponents != null) {
            SQLResult mapping = new SQLResult();

            for (int i = 0; i < resultComponents.size(); i++) {
                Object nextMapping = resultComponents.get(i);
                if (nextMapping instanceof String) {
                    mapping.addColumnResult((String) nextMapping);
                }
                else if (nextMapping instanceof EJBQLExpression) {
                    EntityResult compileEntityResult = compileEntityResult(
                            (EJBQLExpression) nextMapping,
                            i);
                    if (prefetchTree != null) {
                        for (PrefetchTreeNode prefetch : prefetchTree.getChildren()) {
                            if (((EJBQLExpression) nextMapping).getText().equals(
                                    prefetch.getEjbqlPathEntityId())) {
                                EJBQLIdentifier ident = new EJBQLIdentifier(0);
                                ident.text = prefetch.getEjbqlPathEntityId()
                                        + "."
                                        + prefetch.getPath();

                                compileEntityResult = compileEntityResultWithPrefetch(
                                        compileEntityResult,
                                        ident);

                            }
                        }
                    }
                    mapping.addEntityResult(compileEntityResult);

                }
            }

            compiled.setResult(mapping);

        }

        return compiled;
    }