001/*
002 * (C) Copyright 2009 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 *     Florent Guillaume
018 */
019
020package org.nuxeo.runtime.datasource;
021
022import java.util.HashMap;
023import java.util.Map;
024
025import org.nuxeo.common.xmap.annotation.XNode;
026import org.nuxeo.common.xmap.annotation.XNodeMap;
027import org.nuxeo.common.xmap.annotation.XObject;
028import org.nuxeo.runtime.api.Framework;
029import org.w3c.dom.Element;
030import org.w3c.dom.NamedNodeMap;
031import org.w3c.dom.Node;
032
033/**
034 * The descriptor for a Nuxeo-defined datasource.
035 * <p>
036 * The attributes of a {@code <datasource>} element are:
037 * <ul>
038 * <li><b>name</b>: the JNDI name (for instance {@code jdbc/foo})</li>
039 * <li><b>driverClassName</b>: the JDBC driver class name (only for a non-XA datasource)</li>
040 * <li><b>xaDataSource</b>: the XA datasource class name (only for a XA datasource)</li>
041 * </ul>
042 * <p>
043 * To configure the characteristics of the pool:
044 * <ul>
045 * <li><b>maxActive</b>: the maximum number of active connections</li>
046 * <li><b>minIdle</b>: the minimum number of idle connections</li>
047 * <li><b>maxIdle</b>: the maximum number of idle connections</li>
048 * <li><b>maxWait</b>: the maximum number of milliseconds to wait for a connection to be available, or -1 (the default)
049 * to wait indefinitely</li>
050 * <li>... see org.apache.commons.dbcp.BasicDataSource BasicDataSource setters for more</li>
051 * </ul>
052 * <p>
053 * To configure the datasource connections, individual {@code <property>} sub-elements are used.
054 * <p>
055 * For a non-XA datasource, you must specify at least a <b>url</b>:
056 *
057 * <pre>
058 *   &lt;property name=&quot;url&quot;&gt;jdbc:h2:foo/bar&lt;/property&gt;
059 *   &lt;property name=&quot;username&quot;&gt;nuxeo&lt;/property&gt;
060 *   &lt;property name=&quot;password&quot;&gt;nuxeo&lt;/property&gt;
061 * </pre>
062 *
063 * For a XA datasource, see the documentation for your JDBC driver.
064 */
065@XObject("datasource")
066public class DataSourceDescriptor {
067
068    /*
069     * It is not possible to expand the variables in the setters because in tests, values are not available in context.
070     * A clean up needs to be done to have the values during startup.
071     */
072
073    @XNode("@name")
074    protected String name;
075
076    public String getName() {
077        return Framework.expandVars(name);
078    }
079
080    @XNode("@xaDataSource")
081    protected String xaDataSource;
082
083    public String getXaDataSource() {
084        return Framework.expandVars(xaDataSource);
085    }
086
087    @XNode("@dataSource")
088    protected String dataSource;
089
090    public String getDataSource() {
091        return Framework.expandVars(dataSource);
092    }
093
094    @XNode("@driverClassName")
095    protected String driverClasssName;
096
097    public String getDriverClasssName() {
098        return Framework.expandVars(driverClasssName);
099    }
100
101    @XNode("")
102    public Element element;
103
104    @XNodeMap(value = "property", key = "@name", type = HashMap.class, componentType = String.class)
105    public Map<String, String> properties;
106
107    // collect explicit properties and all descriptor attributes
108    public Map<String, String> getAllProperties() {
109        Map<String, String> props = new HashMap<>();
110        properties.forEach((k, v) -> props.put(k, Framework.expandVars(v)));
111        NamedNodeMap attrs = element.getAttributes();
112        for (int i = 0; i < attrs.getLength(); i++) {
113            Node attr = attrs.item(i);
114            props.put(attr.getNodeName(), Framework.expandVars(attr.getNodeValue()));
115        }
116        return props;
117    }
118
119}