1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 package com.sun.star.sdbcx.comp.postgresql; 23 24 import java.util.ArrayList; 25 import java.util.concurrent.atomic.AtomicBoolean; 26 27 import com.sun.star.beans.PropertyValue; 28 import com.sun.star.lang.DisposedException; 29 import com.sun.star.lang.XServiceInfo; 30 import com.sun.star.lang.XSingleComponentFactory; 31 import com.sun.star.lib.uno.helper.ComponentBase; 32 import com.sun.star.lib.uno.helper.Factory; 33 import com.sun.star.sdbc.DriverPropertyInfo; 34 import com.sun.star.sdbc.SQLException; 35 import com.sun.star.sdbc.XConnection; 36 import com.sun.star.sdbc.XDriver; 37 import com.sun.star.sdbc.XDriverManager; 38 import com.sun.star.sdbcx.XDataDefinitionSupplier; 39 import com.sun.star.sdbcx.XTablesSupplier; 40 import com.sun.star.sdbcx.comp.postgresql.util.SharedResources; 41 import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState; 42 import com.sun.star.uno.Exception; 43 import com.sun.star.uno.UnoRuntime; 44 import com.sun.star.uno.XComponentContext; 45 46 public class PostgresqlDriver extends ComponentBase implements XServiceInfo, XDriver, XDataDefinitionSupplier { 47 private static String[] services = new String[] { 48 "com.sun.star.sdbc.Driver", 49 "com.sun.star.sdbcx.Driver" 50 }; 51 private XComponentContext componentContext; 52 private AtomicBoolean isDisposed = new AtomicBoolean(false); 53 54 public static XSingleComponentFactory __getComponentFactory(String implName) { 55 XSingleComponentFactory xSingleComponentFactory = null; 56 if (implName.equals(getImplementationNameStatic())) { 57 xSingleComponentFactory = Factory.createComponentFactory(PostgresqlDriver.class, 58 getImplementationNameStatic(), services); 59 } 60 return xSingleComponentFactory; 61 } 62 63 public PostgresqlDriver(XComponentContext componentContext) { 64 this.componentContext = componentContext; 65 SharedResources.registerClient(componentContext); 66 } 67 68 private static String getImplementationNameStatic() { 69 return PostgresqlDriver.class.getName(); 70 } 71 72 // XComponent: 73 74 @Override 75 protected void postDisposing() { 76 isDisposed.set(true); 77 componentContext = null; 78 SharedResources.revokeClient(); 79 } 80 81 private void checkDisposed() throws DisposedException { 82 if (isDisposed.get()) { 83 throw new DisposedException(); 84 } 85 } 86 87 // XServiceInfo: 88 89 @Override 90 public String getImplementationName() { 91 return getImplementationNameStatic(); 92 } 93 94 @Override 95 public String[] getSupportedServiceNames() { 96 return services.clone(); 97 } 98 99 @Override 100 public boolean supportsService(String serviceName) { 101 for (String service : services) { 102 if (service.equals(serviceName)) { 103 return true; 104 } 105 } 106 return false; 107 } 108 109 // XDriver: 110 111 @Override 112 public boolean acceptsURL(String url) throws SQLException { 113 return url.startsWith("sdbc:postgresql:jdbc:"); 114 } 115 116 @Override 117 public XConnection connect(String url, PropertyValue[] info) throws SQLException { 118 checkDisposed(); 119 XConnection connection = null; 120 if (acceptsURL(url)) { 121 String jdbcUrl = transformUrl(url); 122 System.out.println("Using SDBC URL " + url + " and JDBC URL " + jdbcUrl); 123 124 try { 125 Object driverManagerObject = componentContext.getServiceManager().createInstanceWithContext( 126 "com.sun.star.sdbc.DriverManager", componentContext); 127 XDriverManager driverManager = UnoRuntime.queryInterface(XDriverManager.class, driverManagerObject); 128 129 ArrayList<PropertyValue> properties = new ArrayList<>(); 130 boolean haveJavaClass = false; 131 for (PropertyValue property : info) { 132 if (property.Name.equals("JavaDriverClass")) { 133 haveJavaClass = true; 134 } 135 properties.add(property); 136 } 137 if (!haveJavaClass) { 138 PropertyValue javaClassProperty = new PropertyValue(); 139 javaClassProperty.Name = "JavaDriverClass"; 140 javaClassProperty.Value = "org.postgresql.Driver"; 141 properties.add(javaClassProperty); 142 } 143 PropertyValue[] jdbcInfo = properties.toArray(new PropertyValue[properties.size()]); 144 145 connection = driverManager.getConnectionWithInfo(jdbcUrl, jdbcInfo); 146 if (connection != null) { 147 connection = new PostgresqlConnection(connection, url); 148 } 149 } catch (SQLException sqlException) { 150 throw sqlException; 151 } catch (Exception exception) { 152 throw new SQLException(exception.getMessage(), this, StandardSQLState.SQL_UNABLE_TO_CONNECT.text(), 0, exception); 153 } 154 } 155 return connection; 156 } 157 158 @Override 159 public int getMajorVersion() { 160 return 1; 161 } 162 163 @Override 164 public int getMinorVersion() { 165 return 0; 166 } 167 168 @Override 169 public DriverPropertyInfo[] getPropertyInfo(String url, PropertyValue[] info) throws SQLException { 170 if (!acceptsURL(url)) { 171 return new DriverPropertyInfo[0]; 172 } 173 return new DriverPropertyInfo [] { 174 new DriverPropertyInfo("JavaClassName", "The JDBC driver class name.", true, 175 "com.postgresql.Driver", new String[0]), 176 }; 177 } 178 179 private static String transformUrl(String url) { 180 // 012345678901234567890 181 // sdbc:postgresql:jdbc: 182 return "jdbc:postgresql:" + url.substring(21); 183 } 184 185 // XDataDefinitionSupplier: 186 187 public XTablesSupplier getDataDefinitionByConnection(XConnection connection) throws SQLException { 188 checkDisposed(); 189 return new PostgresqlCatalog((PostgresqlConnection)connection); 190 } 191 192 public XTablesSupplier getDataDefinitionByURL(String url, PropertyValue[] info) throws SQLException { 193 checkDisposed(); 194 if (!acceptsURL(url)) { 195 throw new SQLException(); // FIXME 196 } 197 return getDataDefinitionByConnection(connect(url, info)); 198 } 199 } 200