001: package org.smartlib.pool.core;
002:
003: import java.io.File;
004: import java.io.IOException;
005: import java.util.List;
006: import java.util.ArrayList;
007: import java.util.HashMap;
008:
009: import org.apache.log4j.Logger;
010: import org.apache.xerces.parsers.DOMParser;
011: import org.xml.sax.*;
012: import org.w3c.dom.Document;
013: import org.w3c.dom.Node;
014: import org.w3c.dom.NodeList;
015: import org.w3c.dom.NamedNodeMap;
016:
017: /**
018: * Created by IntelliJ IDEA.
019: * User: kerneldebugger
020: * Date: Sep 28, 2005
021: * Time: 8:05:29 PM
022: * To change this template use File | Settings | File Templates.
023: */
024: public class ConfigFileProcessor {
025:
026: Logger logger = Logger.getLogger(ConfigFileProcessor.class);
027:
028: PoolConfig[] getPoolConfig(String fileName) throws SAXException,
029: SAXNotRecognizedException, IOException,
030: ConnectionPoolException {
031:
032: if (fileName == null)
033: throw new IllegalArgumentException(
034: "Filename cannot be null");
035:
036: File file = new File(fileName);
037: if (!file.exists()) {
038: throw new IllegalArgumentException("File: " + file
039: + " does not exist");
040: }
041:
042: return process(file);
043:
044: }
045:
046: PoolConfig[] getPoolConfig() throws SAXException,
047: SAXNotRecognizedException, IOException,
048: ConnectionPoolException {
049:
050: String fileName = System
051: .getProperty(PoolConstants.CONFIG_FILE_SYSTEM_PROPERTY);
052: if (logger.isDebugEnabled()) {
053: logger.debug("Config File System Property:" + fileName);
054: }
055: return getPoolConfig(fileName);
056:
057: }
058:
059: private PoolConfig[] process(File file) throws SAXException,
060: SAXNotRecognizedException, IOException,
061: ConnectionPoolException {
062:
063: DOMParser xmlParser = new DOMParser();
064: //xmlParser.setFeature("http://xml.org/sax/features/validation", true);
065: xmlParser.setFeature(
066: "http://apache.org/xml/features/validation/schema",
067: true);
068: //xmlParser.setProperty( "http://apache.org/xml/properties/schema/external-schemaLocation",
069: // "D:\\sachin\\work\\smartpool\\project\\conf\\pool-config.xsd");
070: //xmlParser.setProperty( "http://apache.org/xml/properties/schema/external-schemaLocation",
071: // "http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");
072:
073: xmlParser.setErrorHandler(new MyErrorHandler());
074: if (logger.isDebugEnabled()) {
075: logger.debug("Reading file: " + file.getAbsolutePath());
076: }
077: xmlParser.parse(file.getAbsolutePath());
078: Document dom = xmlParser.getDocument();
079:
080: NodeList nodeList = dom.getElementsByTagName("pool");
081: PoolConfig[] configs = new PoolConfig[nodeList.getLength()];
082: for (int i = 0; i < nodeList.getLength(); i++) {
083: Node node = nodeList.item(i);
084: configs[i] = getPoolConfig(node);
085: }
086: validatePoolConfigs(configs);
087: return configs;
088:
089: }
090:
091: private PoolConfig getPoolConfig(Node node)
092: throws ConnectionPoolException {
093: PoolConfig config = new PoolConfig();
094: NodeList list = node.getChildNodes();
095: for (int i = 0; i < list.getLength(); i++) {
096: Node childNode = list.item(i);
097: String nodeName = childNode.getNodeName();
098: if (nodeName != null && nodeName.equals("basic")) {
099: populateBasic(config, childNode);
100: }
101: if (nodeName != null && nodeName.equals("connect-strings")) {
102: populateConnectString(config, childNode);
103: }
104: if (nodeName != null && nodeName.equals("pool-sizing")) {
105: populatePoolSizing(config, childNode);
106: }
107: if (nodeName != null && nodeName.equals("leak-detection")) {
108: populateLeakDetection(config, childNode);
109: }
110: if (nodeName != null && nodeName.equals("external-pooling")) {
111: populateExternalPooling(config, childNode);
112: }
113: }
114: return config;
115:
116: }
117:
118: private void populateExternalPooling(PoolConfig config, Node node)
119: throws ConnectionPoolException {
120:
121: NodeList list = node.getChildNodes();
122: List connList = new ArrayList();
123: for (int i = 0; i < list.getLength(); i++) {
124: Node childNode = list.item(i);
125: String nodeName = childNode.getNodeName();
126: if (nodeName != null) {
127: if (nodeName != null) {
128: if (nodeName.equals("connection-loader-class")) {
129: PoolConfig.ConnectionLoaderClass connectLoaderClasses = new PoolConfig.ConnectionLoaderClass();
130: connectLoaderClasses
131: .setConnectionLoaderClass(getTagValue(childNode));
132: connectLoaderClasses.setName(config
133: .getMultiPoolName()
134: + "."
135: + getAttributeValue(childNode, "name"));
136: connList.add(connectLoaderClasses);
137: }
138: if (nodeName.equals("thread-stickiness")) {
139: config.setThreadStickiness(Boolean
140: .valueOf(getTagValue(childNode)));
141: }
142: }
143:
144: }
145: }
146: config
147: .setConnectionLoaderClass((PoolConfig.ConnectionLoaderClass[]) connList
148: .toArray(new PoolConfig.ConnectionLoaderClass[connList
149: .size()]));
150: }
151:
152: private void populateConnectString(PoolConfig config, Node node)
153: throws ConnectionPoolException {
154:
155: NodeList list = node.getChildNodes();
156: List connList = new ArrayList();
157:
158: for (int i = 0; i < list.getLength(); i++) {
159: Node childNode = list.item(i);
160: String nodeName = childNode.getNodeName();
161: if (nodeName != null) {
162: if (nodeName.equals("connect-string")) {
163: PoolConfig.ConnectionString connectString = new PoolConfig.ConnectionString();
164: connectString
165: .setConnectString(getTagValue(childNode));
166: connectString.setName(config.getMultiPoolName()
167: + "."
168: + getAttributeValue(childNode, "name"));
169: connList.add(connectString);
170: }
171: if (nodeName.equals("thread-stickiness")) {
172: config.setThreadStickiness(Boolean
173: .valueOf(getTagValue(childNode)));
174: }
175: }
176: }
177: config
178: .setConnectionString((PoolConfig.ConnectionString[]) connList
179: .toArray(new PoolConfig.ConnectionString[connList
180: .size()]));
181:
182: }
183:
184: private void populatePoolSizing(PoolConfig config, Node node) {
185:
186: NodeList list = node.getChildNodes();
187: for (int i = 0; i < list.getLength(); i++) {
188: Node childNode = list.item(i);
189: String nodeName = childNode.getNodeName();
190: if (nodeName != null) {
191: if (nodeName.equals("min-connections")) {
192: config.setMinConnections(Integer
193: .valueOf(getTagValue(childNode)));
194: }
195: if (nodeName.equals("max-connections")) {
196: config.setMaxConnections(Integer
197: .valueOf(getTagValue(childNode)));
198: }
199: if (nodeName.equals("increment-by")) {
200: config.setIncrement(Integer
201: .valueOf(getTagValue(childNode)));
202: }
203: if (nodeName.equals("increment-by")) {
204: config.setIncrement(Integer
205: .valueOf(getTagValue(childNode)));
206: }
207: if (nodeName.equals("max-free-connections-for-release")) {
208: config.setMaxConnectionsForRelease(Integer
209: .valueOf(getTagValue(childNode)));
210: }
211: if (nodeName.equals("connection-wait-time-out")) {
212: config.setConnectionWaitTimeOut(Integer
213: .valueOf(getTagValue(childNode)));
214: }
215: if (nodeName.equals("max-connection-idle-time")) {
216: config.setMaxConnectionIdleTime(Integer
217: .valueOf(getTagValue(childNode)));
218: }
219: }
220: }
221: }
222:
223: private void populateLeakDetection(PoolConfig config, Node node) {
224:
225: NodeList list = node.getChildNodes();
226: for (int i = 0; i < list.getLength(); i++) {
227: Node childNode = list.item(i);
228: String nodeName = childNode.getNodeName();
229: if (nodeName != null) {
230: if (nodeName.equals("detect-leaks")) {
231: config.setDetectLeaks(Boolean
232: .valueOf(getTagValue(childNode)));
233: }
234: if (nodeName.equals("leak-time-out")) {
235: config.setLeakTimeOut(Integer
236: .valueOf(getTagValue(childNode)));
237: }
238: if (nodeName.equals("poll-thread-time")) {
239: config.setPollThreadTime(Integer
240: .valueOf(getTagValue(childNode)));
241: }
242: if (nodeName.equals("default-listener")) {
243: config.setDefaultListener(getTagValue(childNode));
244: }
245: }
246:
247: }
248:
249: }
250:
251: private void populateBasic(PoolConfig config, Node node) {
252:
253: NodeList list = node.getChildNodes();
254: for (int i = 0; i < list.getLength(); i++) {
255: Node childNode = list.item(i);
256: String nodeName = childNode.getNodeName();
257: if (nodeName != null) {
258: if (nodeName.equals("pool-name")) {
259: config.setMultiPoolName(getTagValue(childNode));
260: }
261: if (nodeName.equals("default-pool")) {
262: config.setDefaultPool(Boolean
263: .valueOf(getTagValue(childNode)));
264: }
265: if (nodeName.equals("connection-driver")) {
266: config.setDriver(getTagValue(childNode));
267: }
268: if (nodeName.equals("username")) {
269: config.setUserName(getTagValue(childNode));
270: }
271: if (nodeName.equals("password")) {
272: config.setPassword(getTagValue(childNode));
273: }
274: if (nodeName.equals("auto-close")) {
275: config.setAutoClose(Boolean
276: .valueOf(getTagValue(childNode)));
277: }
278: if (nodeName.equals("allow-anonymous-connections")) {
279: config.setAllowAnonymousConnections(Boolean
280: .valueOf(getTagValue(childNode)));
281: }
282: if (nodeName.equals("validator-query")) {
283: config.setValidatorQuery(getTagValue(childNode));
284: }
285: }
286: }
287:
288: }
289:
290: public class MyErrorHandler implements ErrorHandler {
291:
292: public void warning(SAXParseException exception)
293: throws SAXException {
294: logger.fatal("Warning:", exception);
295: }
296:
297: public void error(SAXParseException exception)
298: throws SAXException {
299: logger.fatal("Warning:", exception);
300: }
301:
302: public void fatalError(SAXParseException exception)
303: throws SAXException {
304: logger.fatal("Warning:", exception);
305: }
306:
307: }
308:
309: private String getTagValue(Node nod) {
310:
311: // Some crazy xml hack
312: if (nod.getChildNodes() != null
313: && nod.getChildNodes().getLength() != 0)
314: return nod.getChildNodes().item(0).getNodeValue();
315: else
316: return nod.getNodeValue();
317:
318: }
319:
320: private String getAttributeValue(Node nod, String attrName)
321: throws ConnectionPoolException {
322:
323: // Some crazy xml hack
324: NamedNodeMap map = nod.getAttributes();
325: Node attrNode = map.getNamedItem(attrName);
326: if (attrNode == null)
327: throw new ConnectionPoolException("Attribute '" + attrName
328: + "' of node '" + nod.getNodeName() + "' is null");
329: return attrNode.getNodeValue();
330:
331: }
332:
333: private void validatePoolConfigs(PoolConfig[] configs)
334: throws ConnectionPoolException {
335: for (int i = 0; i < configs.length; i++) {
336: PoolConfig config = configs[i];
337: if (config.getConnectionLoaderClass() != null
338: && config.getConnectionLoaderClass().length == 0)
339: throw new ConnectionPoolException(
340: "Please provide a valid connection provider for pool:"
341: + config.getMultiPoolName());
342: if (config.getConnectionString() != null
343: && config.getConnectionString().length == 0)
344: throw new ConnectionPoolException(
345: "Please provide a valid connection string for pool:"
346: + config.getMultiPoolName());
347: if (config.getConnectionString() != null
348: && config.getConnectionLoaderClass() != null)
349: throw new ConnectionPoolException(
350: "You can specify either external-pooling or connect-strings but not both.");
351:
352: HashMap distinctMap = new HashMap();
353: PoolConfig.ConnectionString[] connectStrings = config
354: .getConnectionString();
355: if (connectStrings != null) {
356: for (int j = 0; j < connectStrings.length; j++) {
357: if (connectStrings[j].getName() == null
358: || connectStrings[j].getName().trim()
359: .length() == 0)
360: throw new ConnectionPoolException(
361: "Connect String name attribute cannot be null");
362: if (connectStrings[j].getConnectString() == null
363: || connectStrings[j].getConnectString()
364: .trim().length() == 0)
365: throw new ConnectionPoolException(
366: "Connect String cannot be null");
367: if (distinctMap.get(connectStrings[j].getName()) != null)
368: throw new ConnectionPoolException(
369: "Connection string name is not unique: "
370: + connectStrings[j].getName());
371: distinctMap.put(connectStrings[j].getName(),
372: "hello");
373: }
374: }
375:
376: distinctMap.clear();
377: PoolConfig.ConnectionLoaderClass[] connectionLoaderClasses = config
378: .getConnectionLoaderClass();
379: if (connectionLoaderClasses != null) {
380: for (int j = 0; j < connectionLoaderClasses.length; j++) {
381: if (connectionLoaderClasses[j].getName() == null
382: || connectionLoaderClasses[j].getName()
383: .trim().length() == 0)
384: throw new ConnectionPoolException(
385: "Connect String name attribute cannot be null");
386: if (connectionLoaderClasses[j]
387: .getConnectionLoaderClass() == null
388: || connectionLoaderClasses[j]
389: .getConnectionLoaderClass().trim()
390: .length() == 0)
391: throw new ConnectionPoolException(
392: "Connect String cannot be null");
393: if (distinctMap.get(connectionLoaderClasses[j]
394: .getName()) != null)
395: throw new ConnectionPoolException(
396: "Connection provider name is not unique: "
397: + connectionLoaderClasses[j]
398: .getName());
399: distinctMap.put(connectionLoaderClasses[j]
400: .getName(), "hello");
401: }
402: }
403:
404: }
405: }
406:
407: }
|