001/*
002 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.directory.sql;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.nuxeo.common.xmap.annotation.XNode;
027import org.nuxeo.common.xmap.annotation.XNodeList;
028import org.nuxeo.common.xmap.annotation.XObject;
029import org.nuxeo.ecm.directory.BaseDirectoryDescriptor;
030import org.nuxeo.ecm.directory.DirectoryException;
031import org.nuxeo.ecm.directory.InverseReference;
032import org.nuxeo.ecm.directory.Reference;
033
034@XObject(value = "directory")
035public class SQLDirectoryDescriptor extends BaseDirectoryDescriptor {
036
037    private static final Log log = LogFactory.getLog(SQLDirectoryDescriptor.class);
038
039    public static final int QUERY_SIZE_LIMIT_DEFAULT = 0;
040
041    public static final boolean AUTO_INCREMENT_ID_FIELD_DEFAULT = false;
042
043    public static final char DEFAULT_CHARACTER_SEPARATOR = ',';
044
045    public static final String[] CREATE_TABLE_POLICIES = { "never", "on_missing_columns", "always", };
046
047    public static final String CREATE_TABLE_POLICY_DEFAULT = "never";
048
049
050    @XNode("dataSource")
051    public String dataSourceName;
052
053    @XNode("dbDriver")
054    public String dbDriver;
055
056    @XNode("dbUrl")
057    public String dbUrl;
058
059    @XNode("dbUser")
060    public String dbUser;
061
062    @XNode("dbPassword")
063    public String dbPassword;
064
065    @XNode("dataFile")
066    public String dataFileName;
067
068    @XNode(value = "dataFileCharacterSeparator", trim = false)
069    public String dataFileCharacterSeparator = ",";
070
071    public String createTablePolicy;
072
073    @XNode("autoincrementIdField")
074    public Boolean autoincrementIdField;
075
076    @XNode("querySizeLimit")
077    private Integer querySizeLimit;
078
079    @XNodeList(value = "references/tableReference", type = TableReference[].class, componentType = TableReference.class)
080    private TableReference[] tableReferences;
081
082    @XNodeList(value = "references/inverseReference", type = InverseReference[].class, componentType = InverseReference.class)
083    private InverseReference[] inverseReferences;
084
085    @XNodeList(value = "filters/staticFilter", type = SQLStaticFilter[].class, componentType = SQLStaticFilter.class)
086    private SQLStaticFilter[] staticFilters;
087
088    @XNode("nativeCase")
089    public Boolean nativeCase;
090
091    @XNode("computeMultiTenantId")
092    private boolean computeMultiTenantId = true;
093
094    public String getDataSourceName() {
095        return dataSourceName;
096    }
097
098    public void setDataSourceName(String dataSourceName) {
099        this.dataSourceName = dataSourceName;
100    }
101
102    public String getDbDriver() {
103        return dbDriver;
104    }
105
106    public String getDbPassword() {
107        return dbPassword;
108    }
109
110    public String getDbUrl() {
111        return dbUrl;
112    }
113
114    public String getDbUser() {
115        return dbUser;
116    }
117
118    public String getDataFileName() {
119        return dataFileName;
120    }
121
122    public char getDataFileCharacterSeparator() {
123        if (dataFileCharacterSeparator == null || dataFileCharacterSeparator.length() == 0) {
124            log.info("Character separator not well set will " + "take the default value, \""
125                    + DEFAULT_CHARACTER_SEPARATOR + "\"");
126            return DEFAULT_CHARACTER_SEPARATOR;
127        }
128
129        if (dataFileCharacterSeparator.length() > 1) {
130            log.warn("More than one character found for character separator, " + "will take the first one \""
131                    + dataFileCharacterSeparator.charAt(0) + "\"");
132        }
133
134        return dataFileCharacterSeparator.charAt(0);
135    }
136
137    public String getCreateTablePolicy() {
138        return createTablePolicy;
139    }
140
141    @XNode("createTablePolicy")
142    public void setCreateTablePolicy(String createTablePolicy) throws DirectoryException {
143        if (createTablePolicy == null) {
144            this.createTablePolicy = CREATE_TABLE_POLICY_DEFAULT;
145            return;
146        }
147        createTablePolicy = createTablePolicy.toLowerCase();
148        boolean validPolicy = false;
149        for (String policy : CREATE_TABLE_POLICIES) {
150            if (createTablePolicy.equals(policy)) {
151                validPolicy = true;
152                break;
153            }
154        }
155        if (!validPolicy) {
156            throw new DirectoryException("invalid value for createTablePolicy: " + createTablePolicy
157                    + ". It should be one of 'never', " + "'on_missing_columns',  or 'always'.");
158        }
159        this.createTablePolicy = createTablePolicy;
160    }
161
162    public Reference[] getInverseReferences() {
163        return inverseReferences;
164    }
165
166    public Reference[] getTableReferences() {
167        return tableReferences;
168    }
169
170    public boolean isAutoincrementIdField() {
171        return autoincrementIdField == null ? AUTO_INCREMENT_ID_FIELD_DEFAULT : autoincrementIdField.booleanValue();
172    }
173
174    public void setAutoincrementIdField(boolean autoincrementIdField) {
175        this.autoincrementIdField = Boolean.valueOf(autoincrementIdField);
176    }
177
178    public void setDbDriver(String dbDriver) {
179        this.dbDriver = dbDriver;
180    }
181
182    public void setDbPassword(String dbPassword) {
183        this.dbPassword = dbPassword;
184    }
185
186    public void setDbUrl(String dbUrl) {
187        this.dbUrl = dbUrl;
188    }
189
190    public void setDbUser(String dbUser) {
191        this.dbUser = dbUser;
192    }
193
194    public void setInverseReferences(InverseReference[] inverseReferences) {
195        this.inverseReferences = inverseReferences;
196    }
197
198    public void setDataFileName(String dataFile) {
199        this.dataFileName = dataFile;
200    }
201
202    public void setTableReferences(TableReference[] tableReferences) {
203        this.tableReferences = tableReferences;
204    }
205
206    public int getQuerySizeLimit() {
207        return querySizeLimit == null ? QUERY_SIZE_LIMIT_DEFAULT : querySizeLimit.intValue();
208    }
209
210    public void setQuerySizeLimit(int querySizeLimit) {
211        this.querySizeLimit = Integer.valueOf(querySizeLimit);
212    }
213
214    public SQLStaticFilter[] getStaticFilters() {
215        if (staticFilters == null) {
216            return new SQLStaticFilter[0];
217        }
218        return staticFilters;
219    }
220
221    /**
222     * Returns {@code true} if a multi tenant id should be computed for this directory, if the directory has support for
223     * multi tenancy, {@code false} otherwise.
224     *
225     * @since 5.6
226     */
227    public boolean isComputeMultiTenantId() {
228        return computeMultiTenantId;
229    }
230
231    @Override
232    public void merge(BaseDirectoryDescriptor other) {
233        super.merge(other);
234        if (other instanceof SQLDirectoryDescriptor) {
235            merge((SQLDirectoryDescriptor) other);
236        }
237    }
238
239    protected void merge(SQLDirectoryDescriptor other) {
240        if (other.dataSourceName != null) {
241            dataSourceName = other.dataSourceName;
242        }
243        if (other.dbDriver != null) {
244            dbDriver = other.dbDriver;
245        }
246        if (other.dbUrl != null) {
247            dbUrl = other.dbUrl;
248        }
249        if (other.dbUser != null) {
250            dbUser = other.dbUser;
251        }
252        if (other.dbPassword != null) {
253            dbPassword = other.dbPassword;
254        }
255        if (other.dataFileName != null) {
256            dataFileName = other.dataFileName;
257        }
258        if (other.dataFileCharacterSeparator != null) {
259            dataFileCharacterSeparator = other.dataFileCharacterSeparator;
260        }
261        if (other.createTablePolicy != null) {
262            createTablePolicy = other.createTablePolicy;
263        }
264        if (other.autoincrementIdField != null) {
265            autoincrementIdField = other.autoincrementIdField;
266        }
267        if (other.querySizeLimit != null) {
268            querySizeLimit = other.querySizeLimit;
269        }
270        if (other.inverseReferences != null && other.inverseReferences.length != 0) {
271            inverseReferences = other.inverseReferences;
272        }
273        if (other.tableReferences != null && other.tableReferences.length != 0) {
274            tableReferences = other.tableReferences;
275        }
276        if (other.staticFilters != null && other.staticFilters.length != 0) {
277            staticFilters = other.staticFilters;
278        }
279        if (other.nativeCase != null) {
280            nativeCase = other.nativeCase;
281        }
282        computeMultiTenantId = other.computeMultiTenantId;
283    }
284
285    @Override
286    public SQLDirectoryDescriptor clone() {
287        SQLDirectoryDescriptor clone = (SQLDirectoryDescriptor) super.clone();
288        // basic fields are already copied by super.clone()
289        if (tableReferences != null) {
290            clone.tableReferences = new TableReference[tableReferences.length];
291            for (int i = 0; i < tableReferences.length; i++) {
292                clone.tableReferences[i] = tableReferences[i].clone();
293            }
294        }
295        if (inverseReferences != null) {
296            clone.inverseReferences = new InverseReference[inverseReferences.length];
297            for (int i = 0; i < inverseReferences.length; i++) {
298                clone.inverseReferences[i] = inverseReferences[i].clone();
299            }
300        }
301        if (staticFilters != null) {
302            clone.staticFilters = new SQLStaticFilter[staticFilters.length];
303            for (int i = 0; i < staticFilters.length; i++) {
304                clone.staticFilters[i] = staticFilters[i].clone();
305            }
306        }
307        return clone;
308    }
309
310    @Override
311    public SQLDirectory newDirectory() {
312        return new SQLDirectory(this);
313    }
314
315}