/*
* Licensed 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import org.jooq.Context;
import org.jooq.Name;
import org.jooq.tools.StringUtils;
/**
* The default implementation for a qualified SQL identifier.
*
* @author Lukas Eder
*/
final class QualifiedName extends AbstractName {
/**
* Generated UID
*/
private static final long serialVersionUID = 8562325639223483938L;
private final UnqualifiedName[] qualifiedName;
QualifiedName(String[] qualifiedName) {
this(qualifiedName, null);
}
QualifiedName(String[] qualifiedName, Boolean quoted) {
this(names(qualifiedName, quoted));
}
QualifiedName(Name[] qualifiedName) {
this.qualifiedName = last(qualifiedName);
}
private QualifiedName(UnqualifiedName[] qualifiedName) {
this.qualifiedName = qualifiedName;
}
private static final UnqualifiedName[] names(String[] qualifiedName, Boolean quoted) {
String[] nonEmpty = nonEmpty(qualifiedName);
UnqualifiedName[] result = new UnqualifiedName[nonEmpty.length];
for (int i = 0; i < nonEmpty.length; i++)
result[i] = new UnqualifiedName(nonEmpty[i], quoted);
return result;
}
private static final UnqualifiedName[] last(Name[] qualifiedName) {
if (qualifiedName instanceof UnqualifiedName[])
return (UnqualifiedName[]) qualifiedName;
UnqualifiedName[] result = new UnqualifiedName[qualifiedName.length];
for (int i = 0; i < qualifiedName.length; i++)
if (qualifiedName[i] instanceof QualifiedName) {
QualifiedName q = (QualifiedName) qualifiedName[i];
result[i] = q.qualifiedName[q.qualifiedName.length - 1];
}
else if (qualifiedName[i] instanceof UnqualifiedName)
result[i] = (UnqualifiedName) qualifiedName[i];
else
result[i] = new UnqualifiedName(qualifiedName[i].last());
return result;
}
private static final String[] nonEmpty(String[] qualifiedName) {
String[] result;
int nulls = 0;
for (int i = 0; i < qualifiedName.length; i++)
if (StringUtils.isEmpty(qualifiedName[i]))
nulls++;
if (nulls > 0) {
result = new String[qualifiedName.length - nulls];
for (int i = qualifiedName.length - 1; i >= 0; i--)
if (StringUtils.isEmpty(qualifiedName[i]))
nulls--;
else
result[i - nulls] = qualifiedName[i];
}
else {
result = qualifiedName.clone();
}
return result;
}
@Override
public final void accept(Context<?> ctx) {
// [#3437] Fully qualify this field only if allowed in the current context
if (ctx.qualify()) {
String separator = "";
for (int i = 0; i < qualifiedName.length; i++) {
ctx.sql(separator).visit(qualifiedName[i]);
separator = ".";
}
}
else {
ctx.visit(qualifiedName[qualifiedName.length - 1]);
}
}
@Override
public final String first() {
return qualifiedName.length > 0 ? qualifiedName[0].last() : null;
}
@Override
public final String last() {
return qualifiedName.length > 0 ? qualifiedName[qualifiedName.length - 1].last() : null;
}
@Override
public final boolean qualified() {
return qualifiedName.length > 1;
}
@Override
public final Name qualifier() {
if (qualifiedName.length <= 1)
return null;
if (qualifiedName.length == 2)
return qualifiedName[0];
UnqualifiedName[] qualifier = new UnqualifiedName[qualifiedName.length - 1];
System.arraycopy(qualifiedName, 0, qualifier, 0, qualifier.length);
return new QualifiedName(qualifier);
}
@Override
public final Name unqualifiedName() {
if (qualifiedName.length <= 1)
return this;
else
return qualifiedName[qualifiedName.length - 1];
}
@Override
public final String[] getName() {
String[] result = new String[qualifiedName.length];
for (int i = 0; i < qualifiedName.length; i++)
result[i] = qualifiedName[i].last();
return result;
}
@Override
public final Name[] parts() {
return qualifiedName.clone();
}
}