001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (C) 2012  Paul Ferraro
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Lesser General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package net.sf.hajdbc.dialect;
019
020import java.sql.DatabaseMetaData;
021import java.sql.SQLException;
022
023import net.sf.hajdbc.AbstractNamed;
024import net.sf.hajdbc.IdentifierNormalizer;
025import net.sf.hajdbc.QualifiedName;
026import net.sf.hajdbc.QualifiedNameFactory;
027import net.sf.hajdbc.util.Strings;
028
029public class StandardQualifiedNameFactory implements QualifiedNameFactory
030{
031        private final IdentifierNormalizer normalizer;
032        private final boolean supportsSchemasInDDL;
033        private final boolean supportsSchemasInDML;
034        
035        public StandardQualifiedNameFactory(DatabaseMetaData metaData, IdentifierNormalizer normalizer) throws SQLException
036        {
037                this.supportsSchemasInDML = metaData.supportsSchemasInDataManipulation();
038                this.supportsSchemasInDDL = metaData.supportsSchemasInTableDefinitions();
039                this.normalizer = normalizer;
040        }
041
042        @Override
043        public QualifiedName createQualifiedName(String schema, String name)
044        {
045                return new StandardQualifiedName(this.normalizer.normalize(schema), this.normalizer.normalize(name), this.supportsSchemasInDDL, this.supportsSchemasInDML);
046        }
047
048        @Override
049        public IdentifierNormalizer getIdentifierNormalizer()
050        {
051                return this.normalizer;
052        }
053
054        @Override
055        public QualifiedName parse(String raw)
056        {
057                int index = raw.indexOf(Strings.DOT);
058                String schema = (index >= 0) ? raw.substring(0, index) : null;
059                String name = (index >= 0) ? raw.substring(index + 1) : raw;
060                return this.createQualifiedName(schema, name);
061        }
062
063        private class StandardQualifiedName extends AbstractNamed<String, QualifiedName> implements QualifiedName
064        {
065                private final String schema;
066                private final String ddlName;
067                private final String dmlName;
068                
069                StandardQualifiedName(String schema, String name, boolean supportsSchemasInDDL, boolean supportsSchemasInDML)
070                {
071                        super(name);
072                        this.schema = schema;
073                        this.ddlName = this.qualify(supportsSchemasInDDL);
074                        this.dmlName = (supportsSchemasInDDL == supportsSchemasInDML) ? this.ddlName : this.qualify(supportsSchemasInDML);
075                }
076
077                @Override
078                public String getSchema()
079                {
080                        return this.schema;
081                }
082
083                @Override
084                public String getDDLName()
085                {
086                        return this.ddlName;
087                }
088
089                @Override
090                public String getDMLName()
091                {
092                        return this.dmlName;
093                }
094
095                private String qualify(boolean supportsSchemas)
096                {
097                        return (supportsSchemas && (this.schema != null)) ? new StringBuilder(this.schema).append(Strings.DOT).append(this.getName()).toString() : this.getName();
098                }
099        }
100}