1 10 package org.mmbase.storage; 11 12 import java.util.*; 13 import org.xml.sax.InputSource ; 14 15 import org.mmbase.storage.search.SearchQueryHandler; 16 import org.mmbase.storage.util.*; 17 18 import org.mmbase.module.core.*; 19 import org.mmbase.clustering.ChangeManager; 20 import org.mmbase.clustering.MMBaseChangeInterface; 21 import org.mmbase.core.CoreField; 22 23 import org.mmbase.util.ResourceLoader; 24 import org.mmbase.util.transformers.CharTransformer; 25 import org.mmbase.util.transformers.Transformers; 26 27 import org.mmbase.util.logging.Logger; 28 import org.mmbase.util.logging.Logging; 29 30 40 public abstract class StorageManagerFactory { 41 42 private static final Logger log = Logging.getLoggerInstance(StorageManagerFactory.class); 43 44 47 protected MMBase mmbase; 48 52 protected Class storageManagerClass; 53 54 57 protected Map attributes; 58 59 62 protected List typeMappings; 63 64 67 protected ChangeManager changeManager; 68 69 70 73 protected final SortedMap disallowedFields = new TreeMap(String.CASE_INSENSITIVE_ORDER); 74 75 81 protected SearchQueryHandler queryHandler; 82 83 87 protected List queryHandlerClasses = new ArrayList(); 88 89 92 protected CharTransformer setSurrogator = null; 93 94 97 protected CharTransformer getSurrogator = null; 98 99 100 104 static private final Class DEFAULT_FACTORY_CLASS = org.mmbase.storage.implementation.database.DatabaseStorageManagerFactory.class; 105 106 113 static public StorageManagerFactory newInstance(MMBase mmbase) 114 throws StorageException { 115 String factoryClassName = mmbase.getInitParameter("storagemanagerfactory"); 117 try { 119 Class factoryClass = DEFAULT_FACTORY_CLASS; 120 if (factoryClassName != null) { 121 factoryClass = Class.forName(factoryClassName); 122 } 123 StorageManagerFactory factory = (StorageManagerFactory)factoryClass.newInstance(); 124 factory.init(mmbase); 125 return factory; 126 } catch (ClassNotFoundException cnfe) { 127 throw new StorageFactoryException(cnfe); 128 } catch (IllegalAccessException iae) { 129 throw new StorageFactoryException(iae); 130 } catch (InstantiationException ie) { 131 throw new StorageFactoryException(ie); 132 } 133 } 134 135 141 static public StorageManagerFactory newInstance() throws StorageException { 142 return newInstance(MMBase.getMMBase()); 144 } 145 146 153 protected final void init(MMBase mmbase) throws StorageError { 154 log.service("initializing Storage Manager factory " + this.getClass().getName()); 155 this.mmbase = mmbase; 156 attributes = Collections.synchronizedMap(new HashMap()); typeMappings = Collections.synchronizedList(new ArrayList()); changeManager = new ChangeManager(); 159 try { 160 log.debug("loading Storage Manager factory " + this.getClass().getName()); 161 load(); 162 } catch (StorageException se) { 163 log.fatal(se.getMessage() + Logging.stackTrace(se)); 165 throw new StorageError(se); 166 } 167 } 168 169 173 public MMBase getMMBase() { 174 return mmbase; 175 } 176 177 186 abstract protected Object instantiateBasicHandler(Class handlerClass); 187 188 201 abstract protected Object instantiateChainedHandler(Class handlerClass, Object previousHandler); 202 203 210 abstract protected SearchQueryHandler instantiateQueryHandler(Object data); 211 212 217 protected void load() throws StorageException { 218 StorageReader reader = getDocumentReader(); 219 if (reader == null) { 220 if (storageManagerClass == null || queryHandlerClasses.size() == 0) { 221 throw new StorageConfigurationException("No storage reader specified, and no default values available."); 222 } else { 223 log.warn("No storage reader specified, continue using default values."); 224 log.debug("Default storage manager : " + storageManagerClass.getName()); 225 log.debug("Default query handler : " + ((Class )queryHandlerClasses.get(0)).getName()); 226 return; 227 } 228 } 229 230 Class configuredClass = reader.getStorageManagerClass(); 232 if (configuredClass != null) { 233 storageManagerClass = configuredClass; 234 } else if (storageManagerClass == null) { 235 throw new StorageConfigurationException("No StorageManager class specified, and no default available."); 236 } 237 238 setAttributes(reader.getAttributes()); 240 241 242 disallowedFields.putAll(reader.getDisallowedFields()); 244 245 String prefix = (String )getAttribute(Attributes.DEFAULT_STORAGE_IDENTIFIER_PREFIX); 247 if (prefix !=null) { 248 for (Iterator i = disallowedFields.entrySet().iterator(); i.hasNext();) { 249 Map.Entry e = (Map.Entry)i.next(); 250 String name = (String ) e.getKey(); 251 String replacement = (String ) e.getValue(); 252 if (replacement == null ) { 253 e.setValue(prefix + "_" + name); 254 } 255 } 256 } 257 258 log.service("get type mappings"); 259 typeMappings.addAll(reader.getTypeMappings()); 260 Collections.sort(typeMappings); 261 262 List configuredClasses = reader.getSearchQueryHandlerClasses(); 266 if (configuredClasses.size() != 0) { 267 queryHandlerClasses = configuredClasses; 268 } else if (queryHandlerClasses.size() == 0) { 269 throw new StorageConfigurationException("No SearchQueryHandler class specified, and no default available."); 270 } 271 log.service("Found queryhandlers " + queryHandlerClasses); 272 Iterator iHandlers = reader.getSearchQueryHandlerClasses().iterator(); 274 Object handler = null; 275 while (iHandlers.hasNext()) { 276 Class handlerClass = (Class ) iHandlers.next(); 277 if (handler == null) { 278 handler = instantiateBasicHandler(handlerClass); 279 } else { 280 handler = instantiateChainedHandler(handlerClass, handler); 281 } 282 } 283 queryHandler = instantiateQueryHandler(handler); 285 286 String surr = (String ) getAttribute(Attributes.SET_SURROGATOR); 287 if (surr != null && ! surr.equals("")) { 288 setSurrogator = Transformers.getCharTransformer(surr, null, "StorageManagerFactory#load", false); 289 } 290 291 surr = (String ) getAttribute(Attributes.GET_SURROGATOR); 292 if (surr != null && ! surr.equals("")) { 293 getSurrogator = Transformers.getCharTransformer(surr, null, "StorageManagerFactory#load", false); 294 } 295 } 296 297 304 public StorageManager getStorageManager() throws StorageException { 305 try { 306 StorageManager storageManager = (StorageManager)storageManagerClass.newInstance(); 307 storageManager.init(this); 308 return storageManager; 309 } catch(InstantiationException ie) { 310 throw new StorageException(ie); 311 } catch(IllegalAccessException iae) { 312 throw new StorageException(iae); 313 } 314 } 315 316 325 public SearchQueryHandler getSearchQueryHandler() throws StorageException { 326 if (queryHandler==null) { 327 throw new StorageException("Cannot obtain a query handler."); 328 } else { 329 return queryHandler; 330 } 331 } 332 333 341 public StorageReader getDocumentReader() throws StorageException { 342 String storagePath = mmbase.getInitParameter("storage"); 344 if (storagePath != null) { 346 try { 347 InputSource resource = ResourceLoader.getConfigurationRoot().getInputSource(storagePath); 348 if (resource == null) { 349 throw new StorageConfigurationException("Storage resource '" + storagePath + "' not found."); 350 } 351 return new StorageReader(this, resource); 352 } catch (java.io.IOException ioe) { 353 throw new StorageConfigurationException(ioe); 354 } 355 } else { 356 return null; 358 } 359 } 360 361 367 public Map getAttributes() { 368 return Collections.unmodifiableMap(attributes); 369 } 370 371 378 public void setAttributes(Map attributes) { 379 this.attributes.putAll(attributes); 380 log.debug("Database attributes " + this.attributes); 381 } 382 383 389 public Object getAttribute(Object key) { 390 return attributes.get(key); 391 } 392 393 401 public void setAttribute(Object key, Object value) { 402 attributes.put(key, value); 403 } 404 405 412 public Scheme getScheme(Object key) { 413 return getScheme(key, null); 414 } 415 416 425 public Scheme getScheme(Object key, String defaultPattern) { 426 Scheme scheme =(Scheme)getAttribute(key); 427 if (scheme == null && defaultPattern != null) { 428 if (attributes.containsKey(key)) return null; 429 scheme = new Scheme(this,defaultPattern); 430 setAttribute(key,scheme); 431 } 432 return scheme; 433 } 434 435 442 public void setScheme(Object key, String pattern) { 443 if (pattern == null || pattern.equals("")) { 444 setAttribute(key,null); 445 } else { 446 setAttribute(key,new Scheme(this,pattern)); 447 } 448 } 449 450 456 public boolean hasOption(Object key) { 457 Object o = getAttribute(key); 458 return (o instanceof Boolean ) && ((Boolean )o).booleanValue(); 459 } 460 461 466 public void setOption(Object key, boolean value) { 467 setAttribute(key, Boolean.valueOf(value)); 468 } 469 470 474 public List getTypeMappings() { 475 return Collections.unmodifiableList(typeMappings); 476 } 477 478 482 public Map getDisallowedFields() { 483 return Collections.unmodifiableSortedMap(disallowedFields); 484 } 485 486 490 protected void setDisallowedFields(Map disallowedFields) { 491 this.disallowedFields.clear(); 492 this.disallowedFields.putAll(disallowedFields); 493 } 494 495 500 public Object getStorageIdentifier() throws StorageException { 501 return getStorageIdentifier(mmbase); 502 } 503 504 523 public Object getStorageIdentifier(Object mmobject) throws StorageException { 524 String id; 525 if (mmobject instanceof StorageManager) { 526 id = mmbase.getBaseName(); 527 } else if (mmobject == mmbase) { 528 id = mmbase.getBaseName()+"_object"; 529 } else if (mmobject instanceof MMObjectBuilder) { 530 id = mmbase.getBaseName()+"_"+((MMObjectBuilder)mmobject).getTableName(); 531 } else if (mmobject instanceof MMObjectNode) { 532 return ((MMObjectNode)mmobject).getIntegerValue("number"); 533 } else if (mmobject instanceof Index) { 534 id = mmbase.getBaseName()+"_"+((Index)mmobject).getParent().getTableName() + "_" + ((Index)mmobject).getName() + "_idx"; 535 } else if (mmobject instanceof String || mmobject instanceof CoreField) { 536 if (mmobject instanceof CoreField) { 537 id = ((CoreField)mmobject).getName(); 538 } else { 539 id = (String )mmobject; 540 } 541 String key = id; 542 if (!hasOption(Attributes.DISALLOWED_FIELD_CASE_SENSITIVE)) { 543 key = key.toLowerCase(); 544 } 545 if (disallowedFields.containsKey(key)) { 546 String newid = (String )disallowedFields.get(key); 547 if (newid == null) { 548 if (hasOption(Attributes.ENFORCE_DISALLOWED_FIELDS)) { 549 throw new StorageException("The name of the field '"+((CoreField)mmobject).getName()+"' is disallowed, and no alternate value is available."); 550 } 551 } else { 552 id = newid; 553 } 554 } 555 } else { 556 throw new StorageException("Cannot obtain identifier for param of type '"+mmobject.getClass().getName()+"."); 557 } 558 559 String maxIdentifierLength = (String )getAttribute(Attributes.MAX_IDENTIFIER_LENGTH); 560 if (maxIdentifierLength != null && !"".equals(maxIdentifierLength)) { 561 try { 562 int maxlength = Integer.parseInt(maxIdentifierLength); 563 if (id.length() > maxlength) { 564 String base = id.substring(0, maxlength - 8); 566 long hashcode = id.hashCode(); 567 if (hashcode < 0) hashcode = Integer.MAX_VALUE + hashcode; 568 569 id = base + (new java.math.BigInteger (""+hashcode)).toString(16); 571 } 572 } catch (NumberFormatException e) { 573 log.warn("Exception parsing the 'max-identifier-length' parameter; ignoring it!"); 574 } 575 } 576 577 String toCase = (String )getAttribute(Attributes.STORAGE_IDENTIFIER_CASE); 578 if ("lower".equals(toCase)) { 579 return id.toLowerCase(); 580 } else if ("upper".equals(toCase)) { 581 return id.toUpperCase(); 582 } else { 583 return id; 584 } 585 } 586 587 592 public ChangeManager getChangeManager() { 593 return changeManager; 594 } 595 596 599 public String getCatalog() { 600 return null; 601 } 602 603 609 abstract public double getVersion(); 610 611 615 abstract public boolean supportsTransactions(); 616 617 618 619 623 public CharTransformer getGetSurrogator() { 624 return getSurrogator; 625 } 626 630 public CharTransformer getSetSurrogator() { 631 return setSurrogator; 632 } 633 634 635 642 public int getTimeZoneOffset(long time) { 643 return TimeZone.getDefault().getOffset(time); 644 } 645 646 647 } 648 | Popular Tags |