View Javadoc

1   /**
2    *
3    * Copyright 2003-2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.geronimo.converter.jboss;
18  
19  import java.io.Reader;
20  import java.io.IOException;
21  import java.util.List;
22  import java.util.ArrayList;
23  import javax.xml.parsers.DocumentBuilderFactory;
24  import javax.xml.parsers.DocumentBuilder;
25  import javax.xml.parsers.ParserConfigurationException;
26  import org.apache.geronimo.converter.DatabaseConversionStatus;
27  import org.apache.geronimo.converter.JDBCPool;
28  import org.apache.geronimo.converter.XADatabasePool;
29  import org.apache.geronimo.converter.AbstractDatabasePool;
30  import org.apache.geronimo.converter.DOMUtils;
31  import org.apache.geronimo.kernel.util.XmlUtil;
32  import org.w3c.dom.Document;
33  import org.w3c.dom.Element;
34  import org.w3c.dom.NodeList;
35  import org.w3c.dom.Node;
36  import org.xml.sax.InputSource;
37  import org.xml.sax.SAXException;
38  
39  /**
40   * Converts database pools from JBoss 4 to Geronimo
41   *
42   * @version $Rev: 428843 $ $Date: 2006-08-04 11:43:59 -0700 (Fri, 04 Aug 2006) $
43   */
44  public class JBoss4DatabaseConverter extends DOMUtils {
45      public static DatabaseConversionStatus convert(Reader dsXml) throws IOException {
46          List status = new ArrayList();
47          List noTx = new ArrayList();
48          List local = new ArrayList();
49          List xa = new ArrayList();
50  
51          DocumentBuilderFactory factory = XmlUtil.newDocumentBuilderFactory();
52          factory.setValidating(false);
53          try {
54              DocumentBuilder builder = factory.newDocumentBuilder();
55              Document doc = builder.parse(new InputSource(dsXml));
56              dsXml.close();
57              parseDocument(doc, status, noTx, local, xa);
58          } catch (ParserConfigurationException e) {
59              throw (IOException)new IOException().initCause(e);
60          } catch (SAXException e) {
61              throw (IOException)new IOException().initCause(e);
62          }
63  
64          DatabaseConversionStatus result = new DatabaseConversionStatus();
65          result.setMessages((String[]) status.toArray(new String[status.size()]));
66          result.setNoTXPools((JDBCPool[]) noTx.toArray(new JDBCPool[noTx.size()]));
67          result.setJdbcPools((JDBCPool[]) local.toArray(new JDBCPool[noTx.size()]));
68          result.setXaPools((XADatabasePool[]) xa.toArray(new XADatabasePool[xa.size()]));
69          return result;
70      }
71  
72      private static void parseDocument(Document doc, List status, List noTx, List local, List xa) {
73          Element datasources = doc.getDocumentElement();
74          if(!datasources.getNodeName().equalsIgnoreCase("datasources")) {
75              if(datasources.getNodeName().equals("connection-factories")) {
76                  status.add("ERROR: Geronimo cannot parse a JBoss data source configured using conection-factories.  This typically means a custom RAR file is required.");
77                  return;
78              } else {
79                  status.add("ERROR: Unrecognized file beginning with "+datasources.getNodeName()+" element.  Expected a JBoss *-ds.xml file.");
80                  return;
81              }
82          }
83          NodeList list = datasources.getChildNodes();
84          for(int i=0; i<list.getLength(); i++) {
85              Node node = list.item(i);
86              if(node.getNodeType() == Node.ELEMENT_NODE) {
87                  String name = node.getNodeName();
88                  if(name.equalsIgnoreCase("no-tx-datasource")) {
89                      addJDBCDataSource((Element)node, status, noTx);
90                  } else if(name.equalsIgnoreCase("local-tx-datasource")) {
91                      addJDBCDataSource((Element)node, status, local);
92                  } else if(name.equalsIgnoreCase("xa-datasource")) {
93                      addXADataSource((Element)node, status, xa);
94                  } else if(name.equalsIgnoreCase("mbean")) {
95                      status.add("Skipping MBean element");
96                  } else {
97                      status.add("WARN: Skipped element "+name);
98                  }
99              }
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 }