1 package org.apache.ojb.broker.metadata; 2 3 17 18 import javax.xml.parsers.ParserConfigurationException ; 19 import javax.xml.parsers.SAXParser ; 20 import javax.xml.parsers.SAXParserFactory ; 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.FileOutputStream ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.OutputStream ; 27 import java.io.PrintWriter ; 28 import java.net.MalformedURLException ; 29 import java.net.URL ; 30 import java.net.URLConnection ; 31 import java.util.Date ; 32 33 import org.apache.commons.lang.SerializationUtils; 34 import org.apache.commons.lang.SystemUtils; 35 import org.apache.ojb.broker.util.ClassHelper; 36 import org.apache.ojb.broker.util.configuration.Configurable; 37 import org.apache.ojb.broker.util.configuration.Configuration; 38 import org.apache.ojb.broker.util.configuration.ConfigurationException; 39 import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator; 40 import org.apache.ojb.broker.util.logging.Logger; 41 import org.apache.ojb.broker.util.logging.LoggerFactory; 42 import org.xml.sax.ContentHandler ; 43 import org.xml.sax.ErrorHandler ; 44 import org.xml.sax.InputSource ; 45 import org.xml.sax.SAXException ; 46 import org.xml.sax.SAXParseException ; 47 import org.xml.sax.XMLReader ; 48 49 58 public class RepositoryPersistor implements Configurable 59 { 60 62 private static Logger log = LoggerFactory.getLogger(RepositoryPersistor.class); 63 64 private static final String SER_FILE_SUFFIX = "serialized"; 65 private static final String SERIALIZED_REPOSITORY_PATH = "serializedRepositoryPath"; 66 67 private boolean useSerializedRepository = false; 68 69 public RepositoryPersistor() 70 { 71 OjbConfigurator.getInstance().configure(this); 72 } 73 74 public void configure(Configuration pConfig) throws ConfigurationException 75 { 76 useSerializedRepository = ((MetadataConfiguration) pConfig).useSerializedRepository(); 77 } 78 79 82 public void writeToFile(DescriptorRepository repository, ConnectionRepository conRepository, OutputStream out) 83 { 84 RepositoryTags tags = RepositoryTags.getInstance(); 85 try 86 { 87 if (log.isDebugEnabled()) 88 log.debug("## Write repository file ##" + 89 repository.toXML() + 90 "## End of repository file ##"); 91 92 93 String eol = SystemUtils.LINE_SEPARATOR; 94 StringBuffer buf = new StringBuffer (); 95 buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + eol); 97 98 buf.append("<!DOCTYPE descriptor-repository SYSTEM \"repository.dtd\" >" + eol + eol); 99 105 buf.append("<!-- OJB RepositoryPersistor generated this file on " + new Date ().toString() + " -->" + eol); 106 107 buf.append(tags.getOpeningTagNonClosingById(RepositoryElements.MAPPING_REPOSITORY) + eol); 108 buf.append(" " + tags.getAttribute(RepositoryElements.REPOSITORY_VERSION, DescriptorRepository.getVersion()) + eol); 109 buf.append(" " + tags.getAttribute(RepositoryElements.ISOLATION_LEVEL, repository.getIsolationLevelAsString()) + eol); 110 buf.append(">" + eol); 111 112 if(conRepository != null) buf.append(eol + eol + conRepository.toXML() + eol + eol); 113 if(repository != null) buf.append(repository.toXML()); 114 115 buf.append(tags.getClosingTagById(RepositoryElements.MAPPING_REPOSITORY)); 116 117 PrintWriter pw = new PrintWriter (out); 118 pw.print(buf.toString()); 119 pw.flush(); 120 pw.close(); 121 } 122 catch (Exception e) 123 { 124 log.error("Could not write to output stream" + out, e); 125 } 126 } 127 128 139 public DescriptorRepository readDescriptorRepository(String filename) 140 throws MalformedURLException , ParserConfigurationException , SAXException , IOException 141 { 142 DescriptorRepository result; 143 if (useSerializedRepository) 144 { 146 Configuration config = OjbConfigurator.getInstance().getConfigurationFor(null); 148 String pathPrefix = config.getString(SERIALIZED_REPOSITORY_PATH, "."); 149 File serFile = new File (pathPrefix + File.separator + filename + "." + SER_FILE_SUFFIX); 150 151 if (serFile.exists() && serFile.length() > 0) 152 { 154 try 155 { 156 long duration = System.currentTimeMillis(); 157 result = deserialize(serFile); 158 log.info("Read serialized repository in " + (System.currentTimeMillis() - duration) + " ms"); 159 } 160 catch (Exception e) 161 { 162 log.error("error in loading serialized repository. Will try to use XML version.", e); 163 result = (DescriptorRepository) buildRepository(filename, DescriptorRepository.class); 164 } 165 } 166 else 167 { 169 long duration = System.currentTimeMillis(); 170 result = (DescriptorRepository) buildRepository(filename, DescriptorRepository.class); 171 log.info("Read repository from file took " + (System.currentTimeMillis() - duration) + " ms"); 172 serialize(result, serFile); 173 } 174 } 175 else 177 { 178 long duration = System.currentTimeMillis(); 179 result = (DescriptorRepository) buildRepository(filename, DescriptorRepository.class); 180 log.info("Read class descriptors took " + (System.currentTimeMillis() - duration) + " ms"); 181 } 182 return result; 183 } 184 185 public DescriptorRepository readDescriptorRepository(InputStream inst) 186 throws MalformedURLException , ParserConfigurationException , SAXException , IOException 187 { 188 long duration = System.currentTimeMillis(); 189 InputSource inSource = new InputSource (inst); 190 DescriptorRepository result = (DescriptorRepository) readMetadataFromXML(inSource, DescriptorRepository.class); 191 log.info("Read class descriptors took " + (System.currentTimeMillis() - duration) + " ms"); 192 return result; 193 } 194 195 198 public ConnectionRepository readConnectionRepository(String filename) 199 throws MalformedURLException , ParserConfigurationException , SAXException , IOException 200 { 201 long duration = System.currentTimeMillis(); 202 ConnectionRepository result = (ConnectionRepository) buildRepository(filename, ConnectionRepository.class); 203 log.info("Read connection repository took " + (System.currentTimeMillis() - duration) + " ms"); 204 return result; 205 } 206 207 210 public ConnectionRepository readConnectionRepository(InputStream inst) 211 throws MalformedURLException , ParserConfigurationException , SAXException , IOException 212 { 213 long duration = System.currentTimeMillis(); 214 InputSource inSource = new InputSource (inst); 215 ConnectionRepository result = (ConnectionRepository) readMetadataFromXML(inSource, ConnectionRepository.class); 216 log.info("Read connection repository took " + (System.currentTimeMillis() - duration) + " ms"); 217 return result; 218 } 219 220 protected DescriptorRepository deserialize(File serFile) 221 { 222 DescriptorRepository result = null; 223 try 224 { 225 FileInputStream fis = new FileInputStream (serFile); 226 result = (DescriptorRepository) SerializationUtils.deserialize(fis); 228 } 229 catch (Exception e) 230 { 231 log.error("Deserialisation failed, using input path: " + serFile.getAbsolutePath(), e); 232 } 233 return result; 234 } 235 236 protected void serialize(DescriptorRepository repository, File file) 237 { 238 try 239 { 240 FileOutputStream fos = new FileOutputStream (file); 241 SerializationUtils.serialize(repository, fos); 243 } 244 catch (Exception e) 245 { 246 log.error("Serialization failed, using output path: " + file.getAbsolutePath(), e); 247 } 248 } 249 250 254 private Object buildRepository(String repositoryFileName, Class targetRepository) 255 throws MalformedURLException , ParserConfigurationException , SAXException , IOException 256 { 257 URL url = buildURL(repositoryFileName); 258 265 267 String pathName = url.toExternalForm(); 268 269 log.info("Building repository from :" + pathName); 270 InputSource source = new InputSource (pathName); 271 URLConnection conn = url.openConnection(); 272 conn.setUseCaches(false); 273 conn.connect(); 274 InputStream in = conn.getInputStream(); 275 source.setByteStream(in); 276 try 277 { 278 return readMetadataFromXML(source, targetRepository); 279 } 280 finally 281 { 282 try 283 { 284 in.close(); 285 } 286 catch (IOException x) 287 { 288 log.warn("unable to close repository input stream [" + x.getMessage() + "]", x); 289 } 290 } 291 } 292 293 297 private Object readMetadataFromXML(InputSource source, Class target) 298 throws MalformedURLException , ParserConfigurationException , SAXException , IOException 299 { 300 boolean validate = false; 302 303 SAXParserFactory factory = SAXParserFactory.newInstance(); 305 log.info("RepositoryPersistor using SAXParserFactory : " + factory.getClass().getName()); 306 if (validate) 307 { 308 factory.setValidating(true); 309 } 310 SAXParser p = factory.newSAXParser(); 311 XMLReader reader = p.getXMLReader(); 312 if (validate) 313 { 314 reader.setErrorHandler(new OJBErrorHandler()); 315 } 316 317 Object result; 318 if (DescriptorRepository.class.equals(target)) 319 { 320 DescriptorRepository repository = new DescriptorRepository(); 322 ContentHandler handler = new RepositoryXmlHandler(repository); 324 reader.setContentHandler(handler); 326 reader.parse(source); 327 result = repository; 328 } 329 else if (ConnectionRepository.class.equals(target)) 330 { 331 ConnectionRepository repository = new ConnectionRepository(); 333 ContentHandler handler = new ConnectionDescriptorXmlHandler(repository); 335 reader.setContentHandler(handler); 337 reader.parse(source); 338 result = repository; 340 } 341 else 342 throw new MetadataException("Could not build a repository instance for '" + target + 343 "', using source " + source); 344 return result; 345 } 346 347 private URL buildURL(String repositoryFileName) throws MalformedURLException 348 { 349 URL url = ClassHelper.getResource(repositoryFileName); 351 352 if (url == null) 354 { 355 try 356 { 357 url = new File (repositoryFileName).toURL(); 358 } 359 catch (MalformedURLException ignore) 360 { 361 } 362 } 363 364 if (url != null) 365 { 366 log.info("OJB Descriptor Repository: " + url); 367 } 368 else 369 { 370 throw new MalformedURLException ("did not find resource " + repositoryFileName); 371 } 372 return url; 373 } 374 375 class OJBErrorHandler implements ErrorHandler 377 { 378 public void warning(SAXParseException exception) 379 throws SAXException 380 { 381 logMessage(exception, false); 382 } 383 384 public void error(SAXParseException exception) 385 throws SAXException 386 { 387 logMessage(exception, false); 388 } 389 390 public void fatalError(SAXParseException exception) 391 throws SAXException 392 { 393 logMessage(exception, true); 394 } 395 396 void logMessage(SAXParseException e, boolean isFatal) 397 { 398 String msg = e.getMessage(); 399 if (isFatal) 400 { 401 log.error("## " + e.getSystemId() + " - line " + e.getLineNumber() + ": " + msg + " ##"); 402 } 403 else 404 { 405 log.warn(e.getSystemId() + " - line " + e.getLineNumber() + ": " + msg); 406 } 407 } 408 } 409 } 410 | Popular Tags |