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 }