/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.jackrabbit.commons.query.qom;

import javax.jcr.RepositoryException;
import javax.jcr.query.qom.Join;
import javax.jcr.query.qom.JoinCondition;
import javax.jcr.query.qom.QueryObjectModelConstants;
import javax.jcr.query.qom.QueryObjectModelFactory;
import javax.jcr.query.qom.Source;

/**
 * Enumeration of the JCR 2.0 join types.
 *
 * @since Apache Jackrabbit 2.0
 */
public enum JoinType {

    INNER(QueryObjectModelConstants.JCR_JOIN_TYPE_INNER),

    LEFT(QueryObjectModelConstants.JCR_JOIN_TYPE_LEFT_OUTER),

    RIGHT(QueryObjectModelConstants.JCR_JOIN_TYPE_RIGHT_OUTER);

    /**
     * JCR name of this join type.
     */
    private final String name;

    private JoinType(String name) {
        this.name = name;
    }

    /**
     * Returns the join of the given sources.
     *
     * @param factory factory for creating the join
     * @param left left join source
     * @param right right join source
     * @param condition join condition
     * @return join
     * @throws RepositoryException if the join can not be created
     */
    public Join join(
            QueryObjectModelFactory factory,
            Source left, Source right, JoinCondition condition)
            throws RepositoryException {
        return factory.join(left, right, name, condition);
    }

    /**
     * Returns the JCR 2.0 name of this join type.
     *
     * @see QueryObjectModelConstants
     * @return JCR name of this join type
     */
    public String toString() {
        return name;
    }

    /**
     * Returns the join type with the given JCR name.
     *
     * @param name JCR name of a join type
     * @return join type with the given name
     * @throws RepositoryException if the given name is unknown
     */
    public static JoinType getJoinTypeByName(String name)
            throws RepositoryException {
        for (JoinType type : JoinType.values()) {
            if (type.name.equals(name)) {
                return type;
            }
        }
        throw new RepositoryException("Unknown join type name: " + name);
    }

}

@@ -1297,16 +1297,30 @@
 PE_INNER
+, %22INNER JOIN%22
 ),%0D%0A%0D%0A  
@@ -1376,16 +1376,35 @@
 FT_OUTER
+, %22LEFT OUTER JOIN%22
 ),%0D%0A%0D%0A  
@@ -1462,16 +1462,36 @@
 HT_OUTER
+, %22RIGHT OUTER JOIN%22
 );%0D%0A%0D%0A  
@@ -1572,24 +1572,57 @@
 ng name;%0D%0A%0D%0A
+    private final String sql;%0D%0A%0D%0A
     private 
@@ -1641,16 +1641,28 @@
 ing name
+, String sql
 ) %7B%0D%0A   
@@ -1677,32 +1677,57 @@
 s.name = name;%0D%0A
+        this.sql = sql;%0D%0A
     %7D%0D%0A%0D%0A    /**
@@ -2286,32 +2286,561 @@
 ion);%0D%0A    %7D%0D%0A%0D%0A
+    /**%0D%0A     * Formats an SQL join with this join type and the given sources and%0D%0A     * join condition. The sources and condition are simply used as-is,%0D%0A     * without any quoting or escaping.%0D%0A     *%0D%0A     * @param left left source%0D%0A     * @param right right source%0D%0A     * @param condition join condition%0D%0A     * @return SQL join, %3Ccode%3Eleft join right%3C/code%3E%0D%0A     */%0D%0A    public String formatSql(Object left, Object right, Object condition) %7B%0D%0A        return left + %22 %22 + sql + %22 %22 + right + %22 ON %22 + condition;%0D%0A    %7D%0D%0A%0D%0A
     /**%0D%0A     * 

Add toString() methods to QOM tree classes