00001
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
00067 public class ControllerParser extends DefaultHandler
00068 {
00070 static Trace
logger = Trace
00071 .getLogger(
ControllerParser.class
00072 .getName());
00073
00075 private XMLReader
parser;
00076
00078 private ControllerFactory
config;
00079 private ControllerSecurityManager
security;
00080 private Controller
controller;
00081 private boolean parseAccept =
false;
00082 private SSLConfiguration
ssl;
00083 String
controllerIP;
00084
00085 private ReportManager
manager;
00086
00095 public ControllerParser(ControllerFactory configure)
throws Exception
00096 {
00097
this.config = configure;
00098
this.controller = configure.getController();
00099
00100
00101
parser = XMLReaderFactory.createXMLReader();
00102
00103
00104
parser.setFeature(
"http://xml.org/sax/features/validation",
true);
00105
00106
00107
parser.setErrorHandler(
this);
00108
00109
00110
parser.setContentHandler(
this);
00111
00112
00113
parser.setEntityResolver(
this);
00114 }
00115
00123 public void readXML(String xml)
throws IOException, SAXException
00124 {
00125
if (xml != null)
00126 {
00127 InputSource input =
new InputSource(
new StringReader(xml));
00128
parser.parse(input);
00129 }
00130
else
00131
throw new IOException(
"Input was null in input source.");
00132 }
00133
00142 public void readXML(String xml,
boolean validateBeforeParsing)
00143
throws IOException, SAXException
00144 {
00145
if (validateBeforeParsing)
00146 {
00147
XmlValidator validator =
new XmlValidator(
ControllerConstants.C_JDBC_CONTROLLER_DTD_FILE, xml
00148 .toString());
00149
if (
logger.isDebugEnabled())
00150 {
00151
if (validator.
isDtdValid())
00152
logger.debug(
Translate.get(
"controller.xml.dtd.validated"));
00153
if (validator.
isXmlValid())
00154
logger.debug(
Translate.get(
"controller.xml.document.validated"));
00155 }
00156
00157
if(validator.
getWarnings().size()>0)
00158 {
00159 ArrayList warnings = validator.
getWarnings();
00160
for (
int i = 0; i < warnings.size(); i++)
00161
logger.warn(
Translate.get(
"virtualdatabase.xml.parsing.warning",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
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
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
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
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
00272 public void startDocument() throws SAXException
00273 {
00274 logger.debug(
Translate.get(
"controller.xml.parsing.document"));
00275 }
00276
00282 public void endDocument() throws SAXException
00283 {
00284 logger.info(
Translate.get(
"controller.xml.done"));
00285 }
00286
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 {
00302
try
00303 {
00304
00305 String controllerPort = atts
00306 .getValue(
ControllerXmlTags.ATT_CONTROLLER_PORT);
00307
if (config.get(ControllerFactory.CONTROLLER_PORT).equals(
00308
"" +
ControllerConstants.DEFAULT_PORT))
00309 {
00310 config.put(ControllerFactory.CONTROLLER_PORT, controllerPort);
00311 config.getController()
00312 .setPortNumber(Integer.parseInt(controllerPort));
00313 }
00314
00315 controllerIP = atts.getValue(
ControllerXmlTags.ATT_CONTROLLER_IP);
00316
if (config.get(ControllerFactory.CONTROLLER_IP).equals(
00317
"" +
ControllerConstants.DEFAULT_IP))
00318 {
00319 config.put(ControllerFactory.CONTROLLER_IP, controllerIP);
00320 config.getController().setIPAddress(controllerIP);
00321 }
00322
00323 String controllerBacklog = atts
00324 .getValue(
ControllerXmlTags.ATT_backlogSize);
00325
if (config.get(ControllerFactory.CONTROLLER_BACKLOG).equals(
00326
"" +
ControllerConstants.DEFAULT_BACKLOG_SIZE))
00327 {
00328 config.put(ControllerFactory.CONTROLLER_BACKLOG, controllerBacklog);
00329 config.getController().setBacklogSize(
00330 Integer.parseInt(controllerBacklog));
00331 }
00332 }
00333
catch (Exception e)
00334 {
00335
throw new SAXException(e.getMessage());
00336 }
00337
00338 }
00339
else if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_INTERNATIONALIZATION))
00340 {
00341 Locale.setDefault(
new Locale(atts
00342 .getValue(
ControllerXmlTags.ATT_LANGUAGE),
""));
00343 }
00344
else if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_REPORT))
00345 {
00346 String enabled =
"true";
00347 config.put(
ControllerXmlTags.ATT_REPORT_ENABLED, enabled);
00348 config.put(
ControllerXmlTags.ATT_REPORT_HIDE_SENSITIVE_DATA, atts
00349 .getValue(
ControllerXmlTags.ATT_REPORT_HIDE_SENSITIVE_DATA));
00350 config.put(
ControllerXmlTags.ATT_REPORT_GENERATE_ON_SHUTDOWN, atts
00351 .getValue(
ControllerXmlTags.ATT_REPORT_GENERATE_ON_SHUTDOWN));
00352 config.put(
ControllerXmlTags.ATT_REPORT_GENERATE_ON_FATAL, atts
00353 .getValue(
ControllerXmlTags.ATT_REPORT_GENERATE_ON_FATAL));
00354 config.put(
ControllerXmlTags.ATT_REPORT_DELETE_ON_SHUTDOWN, atts
00355 .getValue(
ControllerXmlTags.ATT_REPORT_DELETE_ON_SHUTDOWN));
00356 String reportLocation = atts
00357 .getValue(
ControllerXmlTags.ATT_REPORT_REPORT_LOCATION);
00358
00359
if ((reportLocation == null) || reportLocation.equals(
""))
00360 {
00361 String defaultDir = System.getProperty(
"cjdbc.home");
00362
if (defaultDir == null)
00363 {
00364 reportLocation =
".";
00365 }
00366
else
00367 {
00368 reportLocation = defaultDir + File.separator
00369 +
ControllerConstants.DEFAULT_LOG_DIR_NAME;
00370 }
00371 }
00372 config.put(
ControllerXmlTags.ATT_REPORT_REPORT_LOCATION, reportLocation);
00373
00374 config.put(
ControllerXmlTags.ATT_REPORT_ENABLE_FILE_LOGGING, atts
00375 .getValue(
ControllerXmlTags.ATT_REPORT_ENABLE_FILE_LOGGING));
00376 manager =
new ReportManager(controller);
00377 manager.setSettings(config);
00378 controller.setReport(manager);
00379 }
00380
else if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_JMX))
00381 {
00382 config.put(ControllerFactory.JMX_ENABLE,
"true");
00383 }
00384
else if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_HTTP_JMX_ADAPTOR))
00385 {
00386 String adaptorPort = atts
00387 .getValue(
ControllerXmlTags.ATT_JMX_ADAPTOR_PORT);
00388
if (config.get(
JmxConstants.ADAPTOR_TYPE_HTTP) == null)
00389 config.put(
JmxConstants.ADAPTOR_TYPE_HTTP, String.valueOf(adaptorPort));
00390 }
00391
else if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_RMI_JMX_ADAPTOR))
00392 {
00393 String adaptorPort = atts
00394 .getValue(
ControllerXmlTags.ATT_JMX_ADAPTOR_PORT);
00395
if (config.get(
JmxConstants.ADAPTOR_TYPE_RMI) == null)
00396 config.put(
JmxConstants.ADAPTOR_TYPE_RMI, String.valueOf(adaptorPort));
00397
00398 String username = atts
00399 .getValue(
ControllerXmlTags.ATT_JMX_CONNECTOR_USERNAME);
00400 String password = atts
00401 .getValue(
ControllerXmlTags.ATT_JMX_CONNECTOR_PASSWORD);
00402
if (username != null)
00403 config.put(
JmxConstants.CONNECTOR_AUTH_USERNAME, username);
00404
if (password != null)
00405 config.put(
JmxConstants.CONNECTOR_AUTH_PASSWORD, password);
00406 }
00407
else if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_SSL))
00408 {
00409 ssl =
new SSLConfiguration();
00410 ssl.setKeyStore(
new File(atts
00411 .getValue(
ControllerXmlTags.ATT_SSL_KEYSTORE)));
00412 ssl.setKeyStorePassword(atts
00413 .getValue(
ControllerXmlTags.ATT_SSL_KEYSTORE_PASSWORD));
00414 ssl.setKeyStoreKeyPassword(atts
00415 .getValue(
ControllerXmlTags.ATT_SSL_KEYSTORE_KEYPASSWORD));
00416 ssl.setClientAuthenticationRequired(
"true".equals(atts
00417 .getValue(
ControllerXmlTags.ATT_SSL_NEED_CLIENT_AUTH)));
00418 ssl.setTrustStore(
new File(atts
00419 .getValue(
ControllerXmlTags.ATT_SSL_TRUSTSTORE)));
00420 ssl.setTrustStorePassword(atts
00421 .getValue(
ControllerXmlTags.ATT_SSL_TRUSTSTORE_PASSWORD));
00422 }
00423
else if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_DATABASE))
00424 {
00425 String checkPoint = atts
00426 .getValue(
ControllerXmlTags.ATT_DATABASE_CHECKPOINT);
00427 String virtualName = atts.getValue(
ControllerXmlTags.ATT_DATABASE_NAME);
00428 String file = atts.getValue(
ControllerXmlTags.ATT_DATABASE_FILE);
00429
00430
00431
00432
if (file.indexOf(File.separator) == -1)
00433 {
00434
try
00435 {
00436 URL url =
this.getClass().getResource(
"/" + file);
00437 file = url.getFile();
00438 logger.info(
Translate.get(
"controller.configure.using", file));
00439 }
00440
catch (Exception e)
00441 {
00442
throw new SAXException(
Translate.get(
00443
"controller.configure.file.not.found", file));
00444 }
00445 }
00446
00447 file = URLDecoder.decode(file);
00448
00449 File checkExist =
new File(file);
00450
if (checkExist.exists() ==
false)
00451
throw new SAXException(
Translate.get(
00452
"controller.configure.file.not.found", file));
00453
00454
int autoLoad = -1;
00455 String autoLoadString = atts.getValue(
ControllerXmlTags.ATT_DATABASE_ENABLE);
00456
00457
if(autoLoadString.equalsIgnoreCase(
ControllerXmlTags.VAL_true))
00458 autoLoad =
ControllerConstants.AUTO_ENABLE_TRUE;
00459
else if (autoLoadString.equalsIgnoreCase(
ControllerXmlTags.VAL_restore))
00460 autoLoad =
ControllerConstants.AUTO_ENABLE_RESTORE;
00461
else autoLoad =
ControllerConstants.AUTO_ENABLE_FALSE;
00462
00463 logger.info(
Translate.get(
"controller.configure.setup",
new String[]{
00464 virtualName, String.valueOf(autoLoad), checkPoint}));
00465 config.setUpVirtualDatabase(file, virtualName, autoLoad, checkPoint);
00466 }
00467
else if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_SECURITY))
00468 {
00469 security =
new ControllerSecurityManager();
00470
boolean connect =
new Boolean(atts
00471 .getValue(
ControllerXmlTags.ATT_DEFAULT_CONNECT)).booleanValue();
00472 security.setDefaultConnect(connect);
00473 }
00474
else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_JAR))
00475 {
00476
boolean allow =
new Boolean(atts
00477 .getValue(ControllerXmlTags.ATT_JAR_ALLOW_DRIVER)).booleanValue();
00478 security.setAllowAdditionalDriver(allow);
00479 }
00480
else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_CLIENT))
00481 {
00482
boolean localhost =
new Boolean(atts
00483 .getValue(ControllerXmlTags.ATT_ONLY_LOCALHOST)).booleanValue();
00484
boolean allow =
new Boolean(atts.getValue(ControllerXmlTags.ATT_ALLOW))
00485 .booleanValue();
00486 security.setAllowClientShutdown(allow);
00487 security.setAllowLocalClientOnly(localhost);
00488 }
00489
else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_CONSOLE))
00490 {
00491
boolean localhost =
new Boolean(atts
00492 .getValue(ControllerXmlTags.ATT_ONLY_LOCALHOST)).booleanValue();
00493
boolean allow =
new Boolean(atts.getValue(ControllerXmlTags.ATT_ALLOW))
00494 .booleanValue();
00495 security.setAllowConsoleShutdown(allow);
00496 security.setAllowLocalConsoleOnly(localhost);
00497 }
00498
else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_ACCEPT))
00499 parseAccept =
true;
00500
else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_BLOCK))
00501 parseAccept =
false;
00502
else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_HOSTNAME))
00503 security.addHostToSecureList(atts.getValue(ControllerXmlTags.ATT_VALUE),
00504 parseAccept);
00505
else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_IPADDRESS))
00506 security.addHostToSecureList(atts.getValue(ControllerXmlTags.ATT_VALUE),
00507 parseAccept);
00508
else if (name.equalsIgnoreCase(ControllerXmlTags.ELT_IPRANGE))
00509 {
00510 String iprange = atts.getValue(ControllerXmlTags.ATT_VALUE);
00511
try
00512 {
00513 security.addToSecureList(iprange, parseAccept);
00514 }
00515
catch (Exception e)
00516 {
00517 logger.warn(Translate.get(
"controller.configure.invalid.iprange",
00518 iprange));
00519 }
00520 }
00521 }
00522
00531 public void endElement(String uri, String localName, String name)
00532
throws SAXException
00533 {
00534
00535
if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_JMX))
00536 {
00537
try
00538 {
00539 config.setUpJmx();
00540 }
00541
catch (
JmxException jmxEx)
00542 {
00543 logger.error(
Translate.get(
"controller.xml.jmx.setup.failed", jmxEx.getMessage()), jmxEx);
00544 }
00545 }
00546
if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_SECURITY))
00547 {
00548 security.setSslConfig(ssl);
00549 ssl = null;
00550 config.setUpSecurity(security);
00551 }
00552
if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_RMI_JMX_ADAPTOR))
00553 {
00554
if (ssl != null)
00555 {
00556 config.put(
JmxConstants.CONNECTOR_RMI_SSL, ssl);
00557 ssl = null;
00558 }
00559 }
00560
if (name.equalsIgnoreCase(
ControllerXmlTags.ELT_CONTROLLER))
00561 {
00562
00563
if(manager==null)
00564 {
00565 manager =
new ReportManager(controller);
00566 manager.setSettings(null);
00567 controller.setReport(manager);
00568 }
00569 }
00570 logger.debug(
Translate.get(
"controller.xml.parsing.end", name));
00571 }
00572 }