001 /** 002 * 003 * Copyright 2003-2004 The Apache Software Foundation 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.converter.jboss; 018 019 import java.io.Reader; 020 import java.io.IOException; 021 import java.util.List; 022 import java.util.ArrayList; 023 import javax.xml.parsers.DocumentBuilderFactory; 024 import javax.xml.parsers.DocumentBuilder; 025 import javax.xml.parsers.ParserConfigurationException; 026 import org.apache.geronimo.converter.DatabaseConversionStatus; 027 import org.apache.geronimo.converter.JDBCPool; 028 import org.apache.geronimo.converter.XADatabasePool; 029 import org.apache.geronimo.converter.AbstractDatabasePool; 030 import org.apache.geronimo.converter.DOMUtils; 031 import org.apache.geronimo.kernel.util.XmlUtil; 032 import org.w3c.dom.Document; 033 import org.w3c.dom.Element; 034 import org.w3c.dom.NodeList; 035 import org.w3c.dom.Node; 036 import org.xml.sax.InputSource; 037 import org.xml.sax.SAXException; 038 039 /** 040 * Converts database pools from JBoss 4 to Geronimo 041 * 042 * @version $Rev: 428843 $ $Date: 2006-08-04 11:43:59 -0700 (Fri, 04 Aug 2006) $ 043 */ 044 public class JBoss4DatabaseConverter extends DOMUtils { 045 public static DatabaseConversionStatus convert(Reader dsXml) throws IOException { 046 List status = new ArrayList(); 047 List noTx = new ArrayList(); 048 List local = new ArrayList(); 049 List xa = new ArrayList(); 050 051 DocumentBuilderFactory factory = XmlUtil.newDocumentBuilderFactory(); 052 factory.setValidating(false); 053 try { 054 DocumentBuilder builder = factory.newDocumentBuilder(); 055 Document doc = builder.parse(new InputSource(dsXml)); 056 dsXml.close(); 057 parseDocument(doc, status, noTx, local, xa); 058 } catch (ParserConfigurationException e) { 059 throw (IOException)new IOException().initCause(e); 060 } catch (SAXException e) { 061 throw (IOException)new IOException().initCause(e); 062 } 063 064 DatabaseConversionStatus result = new DatabaseConversionStatus(); 065 result.setMessages((String[]) status.toArray(new String[status.size()])); 066 result.setNoTXPools((JDBCPool[]) noTx.toArray(new JDBCPool[noTx.size()])); 067 result.setJdbcPools((JDBCPool[]) local.toArray(new JDBCPool[noTx.size()])); 068 result.setXaPools((XADatabasePool[]) xa.toArray(new XADatabasePool[xa.size()])); 069 return result; 070 } 071 072 private static void parseDocument(Document doc, List status, List noTx, List local, List xa) { 073 Element datasources = doc.getDocumentElement(); 074 if(!datasources.getNodeName().equalsIgnoreCase("datasources")) { 075 if(datasources.getNodeName().equals("connection-factories")) { 076 status.add("ERROR: Geronimo cannot parse a JBoss data source configured using conection-factories. This typically means a custom RAR file is required."); 077 return; 078 } else { 079 status.add("ERROR: Unrecognized file beginning with "+datasources.getNodeName()+" element. Expected a JBoss *-ds.xml file."); 080 return; 081 } 082 } 083 NodeList list = datasources.getChildNodes(); 084 for(int i=0; i<list.getLength(); i++) { 085 Node node = list.item(i); 086 if(node.getNodeType() == Node.ELEMENT_NODE) { 087 String name = node.getNodeName(); 088 if(name.equalsIgnoreCase("no-tx-datasource")) { 089 addJDBCDataSource((Element)node, status, noTx); 090 } else if(name.equalsIgnoreCase("local-tx-datasource")) { 091 addJDBCDataSource((Element)node, status, local); 092 } else if(name.equalsIgnoreCase("xa-datasource")) { 093 addXADataSource((Element)node, status, xa); 094 } else if(name.equalsIgnoreCase("mbean")) { 095 status.add("Skipping MBean element"); 096 } else { 097 status.add("WARN: Skipped element "+name); 098 } 099 } 100 } 101 } 102 103 private static void addDataSourceCommon(Element root, AbstractDatabasePool pool, List status) { 104 pool.setJndiName(getChildText(root, "jndi-name")); 105 pool.setName(pool.getJndiName()); 106 if(pool.getJndiName() != null && pool.getJndiName().indexOf('/') > -1) { 107 status.add("NOTE: pool will use name '"+pool.getJndiName()+"' though Geronimo doesn't put it in JNDI"); 108 } 109 String test = getChildText(root, "min-pool-size"); 110 if(test != null && !test.equals("")) pool.setMinSize(new Integer(test)); 111 test = getChildText(root, "max-pool-size"); 112 if(test != null && !test.equals("")) pool.setMaxSize(new Integer(test)); 113 test = getChildText(root, "blocking-timeout-millis"); 114 if(test != null && !test.equals("")) pool.setBlockingTimeoutMillis(new Integer(test)); 115 test = getChildText(root, "idle-timeout-minutes"); 116 if(test != null && !test.equals("")) pool.setIdleTimeoutMillis(new Integer(Integer.parseInt(test)*60*1000)); 117 pool.setNewConnectionSQL(getChildText(root, "new-connection-sql")); 118 pool.setTestConnectionSQL(getChildText(root, "check-valid-connection-sql")); 119 String sorter = getChildText(root, "exception-sorter-class-name"); 120 if(sorter != null) { 121 if(sorter.indexOf("Oracle") > -1) pool.setVendor(AbstractDatabasePool.VENDOR_ORACLE); 122 if(sorter.indexOf("MySQL") > -1) pool.setVendor(AbstractDatabasePool.VENDOR_MYSQL); 123 if(sorter.indexOf("Sybase") > -1) pool.setVendor(AbstractDatabasePool.VENDOR_SYBASE); 124 if(sorter.indexOf("Informix") > -1) pool.setVendor(AbstractDatabasePool.VENDOR_INFORMIX); 125 } 126 test = getChildText(root, "prepared-statement-cache-size"); 127 if(test != null && !test.equals("")) pool.setStatementCacheSize(new Integer(test)); 128 } 129 130 private static void addJDBCDataSource(Element root, List status, List results) { 131 JDBCPool pool = new JDBCPool(); 132 addDataSourceCommon(root, pool, status); 133 pool.setJdbcURL(getChildText(root, "connection-url")); 134 pool.setDriverClass(getChildText(root, "driver-class")); 135 NodeList list = root.getElementsByTagName("connection-property"); 136 for(int i=0; i<list.getLength(); i++) { 137 Element prop = (Element) list.item(i); 138 pool.getConnectionProperties().setProperty(prop.getAttribute("name"), getText(prop)); 139 } 140 pool.setUsername(getChildText(root, "user-name")); 141 pool.setPassword(getChildText(root, "password")); 142 143 144 if(pool.getName() != null && !pool.getName().equals("")) { 145 results.add(pool); 146 } else { 147 status.add("WARN: Ignoring pool with no JNDI name"); 148 } 149 } 150 151 private static void addXADataSource(Element root, List status, List results) { 152 XADatabasePool pool = new XADatabasePool(); 153 addDataSourceCommon(root, pool, status); 154 pool.setXaDataSourceClass(getChildText(root, "xa-datasource-class")); 155 NodeList list = root.getElementsByTagName("xa-datasource-property"); 156 for(int i=0; i<list.getLength(); i++) { 157 Element prop = (Element) list.item(i); 158 pool.getProperties().setProperty(prop.getAttribute("name"), getText(prop)); 159 } 160 161 if(pool.getName() != null && !pool.getName().equals("")) { 162 results.add(pool); 163 } else { 164 status.add("WARN: Ignoring pool with no JNDI name"); 165 } 166 } 167 168 /* 169 public static void main(String[] args) { 170 File dir = new File("/Users/ammulder/temp/jboss-4.0.3SP1/docs/examples/jca/"); 171 File[] files = dir.listFiles(new FilenameFilter() { 172 public boolean accept(File dir, String name) { 173 return name.endsWith("-ds.xml"); 174 } 175 }); 176 for (int i = 0; i < files.length; i++) { 177 File file = files[i]; 178 System.out.println("Reading "+file.getName()); 179 try { 180 FileReader reader = new FileReader(file); 181 DatabaseConversionStatus status = JBoss4DatabaseConverter.convert(reader); 182 for (int j = 0; j < status.getMessages().length; j++) { 183 String message = status.getMessages()[j]; 184 System.out.println(" "+message); 185 } 186 System.out.println(" FOUND "+status.getNoTXPools().length+" NoTX Pools"); 187 System.out.println(" FOUND "+status.getJdbcPools().length+" JDBC Pools"); 188 System.out.println(" FOUND "+status.getXaPools().length+" XA Pools"); 189 } catch (IOException e) { 190 e.printStackTrace(); 191 } 192 } 193 } */ 194 }