1   /*
2    * PRELYTIS.
3    * Copyright 2007, PRELYTIS S.A., and individual contributors
4    * as indicated by the @author tags. See the copyright.txt file in the
5    * distribution for a full listing of individual contributors.
6    *
7    * This is free software; you can redistribute it and/or modify it
8    * under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */
22  package org.jdbc4olap.xmla;
23  
24  import java.sql.DriverPropertyInfo;
25  import java.sql.SQLException;
26  import java.util.ArrayList;
27  import java.util.List;
28  import java.util.Properties;
29  import java.util.Arrays;
30  
31  import javax.xml.soap.Node;
32  
33  import org.w3c.dom.NodeList;
34  
35  /**
36   * @author <a href="mailto:fsiberchicot@jdbc4olap.org">Florian SIBERCHICOT</a>
37   */
38  class StandardPropertyManager implements PropertyManager {
39  
40      //properties cache is updated when a property is set
41      private boolean upToDate = false;
42      //a server's properties are divided in writable and read-only properties
43      private List<DriverPropertyInfo> driverProperties;
44      private XmlaProperties writableProperties;
45      private Properties readOnlyProperties;
46      private final XmlaConn conn;
47      private final String dataSourceInfo;
48      private final Properties info;
49      //XMLA properties names
50      private static final String CATALOG = "Catalog";
51      private static final String CUBE = "Cube";
52      private static final String DATABASE_PRODUCT_NAME = "ProviderName";
53      private static final String DATABASE_PRODUCT_VERSION = "ProviderVersion";
54      //mapped or deprecated properties
55      private static final String[] FORBIDDEN_PROPERTIES = {"AxisFormat", "Catalog", "Content", "Cube", "DataSourceInfo", "Format", "Password", "UserName"};
56      private static final List<String> FORBIDDEN_LIST = new ArrayList<String>(Arrays.asList(FORBIDDEN_PROPERTIES));
57  
58      public StandardPropertyManager(final XmlaConn conn, final String dataSourceInfo, final Properties info) throws SQLException {
59          this.conn = conn;
60          this.dataSourceInfo = dataSourceInfo;
61          this.info = info;
62          refreshProperties();
63          // @todo Why reset writableProperties here after refreshProperties() call above?
64          writableProperties = new XmlaProperties(info);
65          writableProperties.setProperty("DataSourceInfo", dataSourceInfo);
66      }
67  
68      private String getPropertyValue(final String key) throws SQLException {
69          if (!upToDate) {
70              refreshProperties();
71          }
72          if (writableProperties.containsProperty(key)) {
73              return writableProperties.getProperty(key);
74          } else {
75              return readOnlyProperties.getProperty(key);
76          }
77      }
78  
79      public DriverPropertyInfo[] getDriverPropertyInfo() throws SQLException {
80          if (!upToDate) {
81              refreshProperties();
82          }
83  
84          final DriverPropertyInfo[] res = new DriverPropertyInfo[driverProperties.size()];
85          for (int k = 0; k < driverProperties.size(); k++) {
86              res[k] = driverProperties.get(k);
87          }
88          return res;
89      }
90  
91      private void refreshProperties() throws SQLException {
92  
93          final NodeList rows = conn.discoverProperties();
94  
95          writableProperties = new XmlaProperties();
96          readOnlyProperties = new Properties();
97          driverProperties = new ArrayList<DriverPropertyInfo>();
98          for (int i = 0; i < rows.getLength(); i++) {
99              final NodeList attributes = rows.item(i).getChildNodes();
100             String name = "";
101             String description = "";
102             String value = "";
103             boolean required = false;
104             boolean writable = false;
105 
106             for (int j = 0; j < attributes.getLength(); j++) {
107                 final Node attribute = (Node) attributes.item(j);
108                 final String nodeName = attribute.getNodeName();
109                 final String nodeValue = attribute.getValue();
110                 if ("PropertyName".equals(nodeName)) {
111                     name = nodeValue;
112                 } else if ("PropertyAccessType".equals(nodeName)) {
113                     writable = !nodeValue.equals("Read");
114                 } else if ("PropertyDescription".equals(nodeName)) {
115                     description = nodeValue;
116                 } else if ("IsRequired".equals(nodeName)) {
117                     required = nodeValue.equals("true");
118                 } else if ("Value".equals(nodeName)) {
119                     value = nodeValue;
120                 }
121             }
122 
123             if (name != null && !name.equals("") && !FORBIDDEN_LIST.contains(name)) { // && value!=null
124                 final DriverPropertyInfo driverProperty = new DriverPropertyInfo(name, value);
125                 driverProperty.required = required;
126                 driverProperty.description = description;
127                 if (writable) {
128                     driverProperties.add(driverProperty);
129                 }
130                 if (value != null && !value.equals("")) {
131                     if (writable) {
132                         writableProperties.setProperty(name, value);
133                     } else {
134                         readOnlyProperties.setProperty(name, value);
135                     }
136                 }
137             }
138         }
139         writableProperties.addProperties(info);
140         writableProperties.setProperty("DataSourceInfo", dataSourceInfo);
141         upToDate = true;
142     }
143 
144     public void setCatalog(final String cat) {
145         writableProperties.setProperty(CATALOG, cat);
146     }
147 
148     public String getCatalog() throws SQLException {
149         return getPropertyValue(CATALOG);
150     }
151 
152     public void setCube(final String cube) {
153         writableProperties.setProperty(CUBE, cube);
154     }
155 
156     public String getCube() throws SQLException {
157         return getPropertyValue(CUBE);
158     }
159 
160     public XmlaProperties getXmlaProperties() {
161         return writableProperties;
162     }
163 
164     public String getDatabaseProductName() throws SQLException {
165         return getPropertyValue(DATABASE_PRODUCT_NAME);
166     }
167 
168     public String getDatabaseProductVersion() throws SQLException {
169         return getPropertyValue(DATABASE_PRODUCT_VERSION);
170     }
171 
172 
173 }