00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 package org.objectweb.cjdbc.controller.xml;
00026
00027 import java.io.BufferedReader;
00028 import java.io.File;
00029 import java.io.FileReader;
00030 import java.io.IOException;
00031 import java.io.InputStream;
00032 import java.io.StringReader;
00033 import java.net.URL;
00034 import java.net.URLDecoder;
00035 import java.util.ArrayList;
00036 import java.util.Locale;
00037
00038 import org.objectweb.cjdbc.common.exceptions.ExceptionTypes;
00039 import org.objectweb.cjdbc.common.i18n.Translate;
00040 import org.objectweb.cjdbc.common.jmx.JmxConstants;
00041 import org.objectweb.cjdbc.common.jmx.JmxException;
00042 import org.objectweb.cjdbc.common.log.Trace;
00043 import org.objectweb.cjdbc.common.net.SSLConfiguration;
00044 import org.objectweb.cjdbc.common.xml.ControllerXmlTags;
00045 import org.objectweb.cjdbc.common.xml.XmlValidator;
00046 import org.objectweb.cjdbc.controller.core.Controller;
00047 import org.objectweb.cjdbc.controller.core.ControllerConstants;
00048 import org.objectweb.cjdbc.controller.core.ControllerFactory;
00049 import org.objectweb.cjdbc.controller.core.ReportManager;
00050 import org.objectweb.cjdbc.controller.core.security.ControllerSecurityManager;
00051 import org.xml.sax.Attributes;
00052 import org.xml.sax.InputSource;
00053 import org.xml.sax.SAXException;
00054 import org.xml.sax.SAXParseException;
00055 import org.xml.sax.XMLReader;
00056 import org.xml.sax.helpers.DefaultHandler;
00057 import org.xml.sax.helpers.XMLReaderFactory;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 public class ControllerParser extends DefaultHandler
00068 {
00069
00070 static Trace logger = Trace
00071 .getLogger(ControllerParser.class
00072 .getName());
00073
00074
00075 private XMLReader parser;
00076
00077
00078 private ControllerFactory config;
00079 private ControllerSecurityManager security;
00080 private Controller controller;
00081 private boolean parseAccept = false;
00082 private SSLConfiguration ssl;
00083 private String controllerIP;
00084 private ReportManager manager;
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 public ControllerParser(ControllerFactory configure) throws Exception
00095 {
00096 this.config = configure;
00097 this.controller = configure.getController();
00098
00099
00100 parser = XMLReaderFactory.createXMLReader();
00101
00102
00103 parser.setFeature("http://xml.org/sax/features/validation", true);
00104
00105
00106 parser.setErrorHandler(this);
00107
00108
00109 parser.setContentHandler(this);
00110
00111
00112 parser.setEntityResolver(this);
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122 public void readXML(String xml) throws IOException, SAXException
00123 {
00124 if (xml != null)
00125 {
00126 InputSource input = new InputSource(new StringReader(xml));
00127 parser.parse(input);
00128 }
00129 else
00130 throw new IOException("Input was null in input source.");
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 public void readXML(String xml, boolean validateBeforeParsing)
00142 throws IOException, SAXException
00143 {
00144 if (validateBeforeParsing)
00145 {
00146 XmlValidator validator = new XmlValidator(
00147 ControllerConstants.C_JDBC_CONTROLLER_DTD_FILE, xml.toString());
00148 if (logger.isDebugEnabled())
00149 {
00150 if (validator.isDtdValid())
00151 logger.debug(Translate.get("controller.xml.dtd.validated"));
00152 if (validator.isXmlValid())
00153 logger.debug(Translate.get("controller.xml.document.validated"));
00154 }
00155
00156 if (validator.getWarnings().size() > 0)
00157 {
00158 ArrayList warnings = validator.getWarnings();
00159 for (int i = 0; i < warnings.size(); i++)
00160 logger.warn(Translate.get("virtualdatabase.xml.parsing.warning",
00161 warnings.get(i)));
00162 }
00163
00164 if (!validator.isDtdValid())
00165 logger.error(Translate.get("controller.xml.dtd.not.validated"));
00166 if (!validator.isXmlValid())
00167 logger.error(Translate.get("controller.xml.document.not.validated"));
00168
00169 ArrayList errors = validator.getExceptions();
00170 for (int i = 0; i < errors.size(); i++)
00171 logger.error(((Exception) errors.get(i)).getMessage());
00172
00173 if (!validator.isValid())
00174 throw new SAXException(ExceptionTypes.XML_DOCUMENT_INVALID);
00175 }
00176 readXML(xml);
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 public void readXML(FileReader fileReader, boolean validateBeforeParsing)
00188 throws IOException, SAXException
00189 {
00190 if (fileReader != null)
00191 {
00192
00193
00194 BufferedReader in = new BufferedReader(fileReader);
00195 StringBuffer xml = new StringBuffer();
00196 String line;
00197 do
00198 {
00199 line = in.readLine();
00200 if (line != null)
00201 xml.append(line.trim());
00202 }
00203 while (line != null);
00204
00205 readXML(xml.toString(), validateBeforeParsing);
00206 }
00207 else
00208 {
00209 throw new IOException("Input was null in input source.");
00210 }
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 public void fatalError(SAXParseException e) throws SAXException
00221 {
00222 logger.error(Translate.get("controller.xml.parsing.fatal", new String[]{
00223 e.getPublicId(), String.valueOf(e.getLineNumber()),
00224 String.valueOf(e.getColumnNumber()), e.getMessage()}));
00225 throw e;
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235 public void error(SAXParseException e) throws SAXException
00236 {
00237 logger.error(Translate.get("controller.xml.parsing.error", new String[]{
00238 e.getPublicId(), String.valueOf(e.getLineNumber()),
00239 String.valueOf(e.getColumnNumber()), e.getMessage()}));
00240 throw e;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 public InputSource resolveEntity(String publicId, String systemId)
00252 throws SAXException
00253 {
00254 logger.debug(Translate.get("controller.xml.dtd.using",
00255 ControllerConstants.C_JDBC_CONTROLLER_DTD_FILE));
00256 InputStream stream = ControllerParser.class.getResourceAsStream("/"
00257 + ControllerConstants.C_JDBC_CONTROLLER_DTD_FILE);
00258 if (stream == null)
00259 {
00260 throw new SAXException(Translate.get("controller.xml.dtd.not.found",
00261 ControllerConstants.C_JDBC_CONTROLLER_DTD_FILE));
00262 }
00263
00264 return new InputSource(stream);
00265 }
00266
00267
00268
00269
00270
00271
00272 public void startDocument() throws SAXException
00273 {
00274 logger.debug(Translate.get("controller.xml.parsing.document"));
00275 }
00276
00277
00278
00279
00280
00281
00282 public void endDocument() throws SAXException
00283 {
00284 logger.info(Translate.get("controller.xml.done"));
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 public void startElement(String uri, String localName, String name,
00297 Attributes atts) throws SAXException
00298 {
00299 logger.debug(Translate.get("controller.xml.parsing.start", name));
00300 if (name.equalsIgnoreCase(ControllerXmlTags.ELT_CONTROLLER))
00301 configureController(atts);
00302 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_INTERNATIONALIZATION))
00303 {
00304 Locale.setDefault(new Locale(atts
00305 .getValue(ControllerXmlTags.ATT_LANGUAGE), ""));
00306 }
00307 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_REPORT))
00308 configureReport(atts);
00309 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_JMX))
00310 {
00311 config.put(ControllerFactory.JMX_ENABLE, "true");
00312 }
00313 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_HTTP_JMX_ADAPTOR))
00314 configureHttpJmxAdaptor(atts);
00315 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_RMI_JMX_ADAPTOR))
00316 configureRmiJmxAdaptor(atts);
00317 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_SSL))
00318 configureSSL(atts);
00319 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_VIRTUAL_DATABASE))
00320 configureVirtualDatabase(atts);
00321 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_SECURITY))
00322 {
00323 security = new ControllerSecurityManager();
00324 boolean connect = new Boolean(atts
00325 .getValue(ControllerXmlTags.ATT_DEFAULT_CONNECT)).booleanValue();
00326 security.setDefaultConnect(connect);
00327 }
00328 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_JAR))
00329 {
00330 boolean allow = new Boolean(atts
00331 .getValue(ControllerXmlTags.ATT_JAR_ALLOW_DRIVER)).booleanValue();
00332 security.setAllowAdditionalDriver(allow);
00333 }
00334 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_CLIENT))
00335 configureClient(atts);
00336 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_CONSOLE))
00337 configureConsole(atts);
00338 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_ACCEPT))
00339 parseAccept = true;
00340 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_BLOCK))
00341 parseAccept = false;
00342 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_HOSTNAME))
00343 security.addHostToSecureList(atts.getValue(ControllerXmlTags.ATT_VALUE),
00344 parseAccept);
00345 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_IPADDRESS))
00346 security.addHostToSecureList(atts.getValue(ControllerXmlTags.ATT_VALUE),
00347 parseAccept);
00348 else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_IPRANGE))
00349 configureIpRange(atts);
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 public void endElement(String uri, String localName, String name)
00361 throws SAXException
00362 {
00363
00364 if (name.equalsIgnoreCase(ControllerXmlTags.ELT_JMX))
00365 {
00366 try
00367 {
00368 config.setUpJmx();
00369 }
00370 catch (JmxException jmxEx)
00371 {
00372 logger.error(Translate.get("controller.xml.jmx.setup.failed", jmxEx
00373 .getMessage()), jmxEx);
00374 }
00375 }
00376 if (name.equalsIgnoreCase(ControllerXmlTags.ELT_SECURITY))
00377 {
00378 security.setSslConfig(ssl);
00379 ssl = null;
00380 config.setUpSecurity(security);
00381 }
00382 if (name.equalsIgnoreCase(ControllerXmlTags.ELT_RMI_JMX_ADAPTOR))
00383 {
00384 if (ssl != null)
00385 {
00386 config.put(JmxConstants.CONNECTOR_RMI_SSL, ssl);
00387 ssl = null;
00388 }
00389 }
00390 if (name.equalsIgnoreCase(ControllerXmlTags.ELT_CONTROLLER))
00391 {
00392
00393 if (manager == null)
00394 {
00395 manager = new ReportManager(controller);
00396 manager.setSettings(null);
00397 controller.setReport(manager);
00398 }
00399 }
00400 logger.debug(Translate.get("controller.xml.parsing.end", name));
00401 }
00402
00403
00404
00405
00406
00407
00408 private void configureClient(Attributes atts)
00409 {
00410 {
00411 boolean localhost = new Boolean(atts
00412 .getValue(ControllerXmlTags.ATT_ONLY_LOCALHOST)).booleanValue();
00413 boolean allow = new Boolean(atts.getValue(ControllerXmlTags.ATT_ALLOW))
00414 .booleanValue();
00415 security.setAllowClientShutdown(allow);
00416 security.setAllowLocalClientOnly(localhost);
00417 }
00418 }
00419
00420
00421
00422
00423
00424
00425 private void configureConsole(Attributes atts)
00426 {
00427 {
00428 boolean localhost = new Boolean(atts
00429 .getValue(ControllerXmlTags.ATT_ONLY_LOCALHOST)).booleanValue();
00430 boolean allow = new Boolean(atts.getValue(ControllerXmlTags.ATT_ALLOW))
00431 .booleanValue();
00432 security.setAllowConsoleShutdown(allow);
00433 security.setAllowLocalConsoleOnly(localhost);
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443 private void configureController(Attributes atts) throws SAXException
00444 {
00445 try
00446 {
00447 String controllerPort = atts
00448 .getValue(ControllerXmlTags.ATT_CONTROLLER_PORT);
00449 if (config.get(ControllerFactory.CONTROLLER_PORT).equals(
00450 String.valueOf(ControllerConstants.DEFAULT_PORT)))
00451 {
00452 config.put(ControllerFactory.CONTROLLER_PORT, controllerPort);
00453 config.getController().setPortNumber(Integer.parseInt(controllerPort));
00454 }
00455
00456 controllerIP = atts.getValue(ControllerXmlTags.ATT_CONTROLLER_IP);
00457 if (config.get(ControllerFactory.CONTROLLER_IP).equals(
00458 String.valueOf(ControllerConstants.DEFAULT_IP)))
00459 {
00460 config.put(ControllerFactory.CONTROLLER_IP, controllerIP);
00461 config.getController().setIPAddress(controllerIP);
00462 }
00463
00464 String controllerBacklog = atts
00465 .getValue(ControllerXmlTags.ATT_backlogSize);
00466 if (config.get(ControllerFactory.CONTROLLER_BACKLOG).equals(
00467 String.valueOf(ControllerConstants.DEFAULT_BACKLOG_SIZE)))
00468 {
00469 config.put(ControllerFactory.CONTROLLER_BACKLOG, controllerBacklog);
00470 config.getController().setBacklogSize(
00471 Integer.parseInt(controllerBacklog));
00472 }
00473 }
00474 catch (Exception e)
00475 {
00476 throw new SAXException(e.getMessage());
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485 private void configureHttpJmxAdaptor(Attributes atts)
00486 {
00487 String adaptorPort = atts.getValue(ControllerXmlTags.ATT_JMX_ADAPTOR_PORT);
00488 if (config.get(JmxConstants.ADAPTOR_TYPE_HTTP) == null)
00489 config.put(JmxConstants.ADAPTOR_TYPE_HTTP, String.valueOf(adaptorPort));
00490 }
00491
00492
00493
00494
00495
00496
00497 private void configureIpRange(Attributes atts)
00498 {
00499 {
00500 String iprange = atts.getValue(ControllerXmlTags.ATT_VALUE);
00501 try
00502 {
00503 security.addToSecureList(iprange, parseAccept);
00504 }
00505 catch (Exception e)
00506 {
00507 logger.warn(Translate.get("controller.configure.invalid.iprange",
00508 iprange));
00509 }
00510 }
00511 }
00512
00513
00514
00515
00516
00517
00518 private void configureReport(Attributes atts)
00519 {
00520 config.put(ControllerXmlTags.ATT_REPORT_ENABLED, "true");
00521 config.put(ControllerXmlTags.ATT_REPORT_HIDE_SENSITIVE_DATA, atts
00522 .getValue(ControllerXmlTags.ATT_REPORT_HIDE_SENSITIVE_DATA));
00523 config.put(ControllerXmlTags.ATT_REPORT_GENERATE_ON_SHUTDOWN, atts
00524 .getValue(ControllerXmlTags.ATT_REPORT_GENERATE_ON_SHUTDOWN));
00525 config.put(ControllerXmlTags.ATT_REPORT_GENERATE_ON_FATAL, atts
00526 .getValue(ControllerXmlTags.ATT_REPORT_GENERATE_ON_FATAL));
00527 config.put(ControllerXmlTags.ATT_REPORT_DELETE_ON_SHUTDOWN, atts
00528 .getValue(ControllerXmlTags.ATT_REPORT_DELETE_ON_SHUTDOWN));
00529 String reportLocation = atts
00530 .getValue(ControllerXmlTags.ATT_REPORT_REPORT_LOCATION);
00531
00532 if ((reportLocation == null) || reportLocation.equals(""))
00533 {
00534 String defaultDir = System.getProperty("cjdbc.home");
00535 if (defaultDir == null)
00536 {
00537 reportLocation = ".";
00538 }
00539 else
00540 {
00541 reportLocation = defaultDir + File.separator
00542 + ControllerConstants.DEFAULT_LOG_DIR_NAME;
00543 }
00544 }
00545 config.put(ControllerXmlTags.ATT_REPORT_REPORT_LOCATION, reportLocation);
00546
00547 config.put(ControllerXmlTags.ATT_REPORT_ENABLE_FILE_LOGGING, atts
00548 .getValue(ControllerXmlTags.ATT_REPORT_ENABLE_FILE_LOGGING));
00549 manager = new ReportManager(controller);
00550 manager.setSettings(config);
00551 controller.setReport(manager);
00552 }
00553
00554
00555
00556
00557
00558
00559 private void configureRmiJmxAdaptor(Attributes atts)
00560 {
00561 String adaptorPort = atts.getValue(ControllerXmlTags.ATT_JMX_ADAPTOR_PORT);
00562 if (config.get(JmxConstants.ADAPTOR_TYPE_RMI) == null)
00563 config.put(JmxConstants.ADAPTOR_TYPE_RMI, String.valueOf(adaptorPort));
00564
00565 String username = atts
00566 .getValue(ControllerXmlTags.ATT_JMX_CONNECTOR_USERNAME);
00567 String password = atts
00568 .getValue(ControllerXmlTags.ATT_JMX_CONNECTOR_PASSWORD);
00569 if (username != null)
00570 config.put(JmxConstants.CONNECTOR_AUTH_USERNAME, username);
00571 if (password != null)
00572 config.put(JmxConstants.CONNECTOR_AUTH_PASSWORD, password);
00573 }
00574
00575
00576
00577
00578
00579
00580 private void configureSSL(Attributes atts)
00581 {
00582 ssl = new SSLConfiguration();
00583 ssl
00584 .setKeyStore(new File(atts.getValue(ControllerXmlTags.ATT_SSL_KEYSTORE)));
00585 ssl.setKeyStorePassword(atts
00586 .getValue(ControllerXmlTags.ATT_SSL_KEYSTORE_PASSWORD));
00587 ssl.setKeyStoreKeyPassword(atts
00588 .getValue(ControllerXmlTags.ATT_SSL_KEYSTORE_KEYPASSWORD));
00589 ssl.setClientAuthenticationRequired("true".equals(atts
00590 .getValue(ControllerXmlTags.ATT_SSL_NEED_CLIENT_AUTH)));
00591 ssl.setTrustStore(new File(atts
00592 .getValue(ControllerXmlTags.ATT_SSL_TRUSTSTORE)));
00593 ssl.setTrustStorePassword(atts
00594 .getValue(ControllerXmlTags.ATT_SSL_TRUSTSTORE_PASSWORD));
00595 }
00596
00597
00598
00599
00600
00601
00602
00603 private void configureVirtualDatabase(Attributes atts) throws SAXException
00604 {
00605 String checkPoint = atts
00606 .getValue(ControllerXmlTags.ATT_VIRTUAL_DATABASE_CHECKPOINT);
00607 String virtualName = atts
00608 .getValue(ControllerXmlTags.ATT_VIRTUAL_DATABASE_NAME);
00609 String file = atts.getValue(ControllerXmlTags.ATT_VIRTUAL_DATABASE_FILE);
00610
00611
00612
00613 if (file.indexOf(File.separator) == -1)
00614 {
00615 try
00616 {
00617 URL url = this.getClass().getResource("/" + file);
00618 file = url.getFile();
00619 logger.info(Translate.get("controller.configure.using", file));
00620 }
00621 catch (Exception e)
00622 {
00623 throw new SAXException(Translate.get(
00624 "controller.configure.file.not.found", file));
00625 }
00626 }
00627
00628 file = URLDecoder.decode(file);
00629
00630 File checkExist = new File(file);
00631 if (checkExist.exists() == false)
00632 throw new SAXException(Translate.get(
00633 "controller.configure.file.not.found", file));
00634
00635 int autoLoad = -1;
00636 String autoLoadString = atts
00637 .getValue(ControllerXmlTags.ATT_VIRTUAL_DATABASE_AUTO_ENABLE);
00638
00639 if (autoLoadString.equalsIgnoreCase(ControllerXmlTags.VAL_true))
00640 autoLoad = ControllerConstants.AUTO_ENABLE_TRUE;
00641 else if (autoLoadString.equalsIgnoreCase(ControllerXmlTags.VAL_force))
00642 autoLoad = ControllerConstants.AUTO_ENABLE_FORCE;
00643 else
00644 autoLoad = ControllerConstants.AUTO_ENABLE_FALSE;
00645
00646 logger.info(Translate.get("controller.configure.setup", new String[]{
00647 virtualName, String.valueOf(autoLoad), checkPoint}));
00648 config.setUpVirtualDatabase(file, virtualName, autoLoad, checkPoint);
00649 }
00650
00651 }