Changeset 4096
- Timestamp:
- Jan 22, 2008, 2:22:03 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/build.xml
r4095 r4096 133 133 <!-- pattern for configuration files use by copy.config --> 134 134 <patternset id="config.files"> 135 <include name="* .*" />135 <include name="**/*.*" /> 136 136 <exclude name="web.xml" /> 137 137 <exclude name="readme.txt" /> -
trunk/doc/src/docbook/appendix/extended_properties.xml
r3996 r4096 123 123 </itemizedlist> 124 124 125 <bridgehead>Multiple configuration files</bridgehead> 126 <para> 127 Starting with BASE 2.6 it is possible to use multiple configuration 128 files for extended properties. This is useful only if you want to add 129 new columns. To remove or change existing columns you still have 130 to modify the original extended properties file. It is rather simple 131 to use this feature. Create a new subdirectory with the name 132 <filename>extended-properties</filename> in the same directory as 133 the <filename>extended-properties.xml</filename>. In this directory 134 you can put additional extended property files. They should have the 135 same format as the default file. 136 </para> 137 138 <tip> 139 We recommend that you don't modify the default <filename>extended-properties.xml</filename> 140 file at all (unless you want to remove some of the columns). This will make it 141 easier when upgrading BASE since you don't have to worry about losing 142 your own changes. 143 </tip> 125 144 126 145 <bridgehead>Format of the extended-properties.xml file</bridgehead> -
trunk/src/core/net/sf/basedb/core/Application.java
r4078 r4096 29 29 import net.sf.basedb.core.data.SchemaVersionData; 30 30 import net.sf.basedb.core.authentication.Authenticator; 31 import net.sf.basedb.util.FileUtil; 32 import net.sf.basedb.util.RegexpFileFilter; 31 33 import net.sf.basedb.util.timer.Scheduler; 32 34 35 import java.util.ArrayList; 33 36 import java.util.Calendar; 34 37 import java.util.GregorianCalendar; 35 38 import java.util.HashSet; 39 import java.util.List; 36 40 import java.util.Map; 37 41 import java.util.HashMap; … … 394 398 log.info("db.queries = " + queryFile); 395 399 396 extendedPropertiesFile = Config.getString("db.extended-properties" );400 extendedPropertiesFile = Config.getString("db.extended-properties", "/extended-properties.xml"); 397 401 log.info("db.extended-properties = " + extendedPropertiesFile); 398 402 399 rawDataTypesFile = Config.getString("db.raw-data-types" );403 rawDataTypesFile = Config.getString("db.raw-data-types", "/raw-data-types.xml"); 400 404 log.info("db.raw-data-types = " + rawDataTypesFile); 401 405 … … 707 711 @see ExtendedProperties 708 712 */ 709 static String getExtendedPropertiesFile() 710 { 711 return extendedPropertiesFile; 713 static List<String> getExtendedPropertyFiles() 714 { 715 List<String> files = new ArrayList<String>(); 716 // Main extended properties file 717 files.add(extendedPropertiesFile); 718 // Scan extended-properties directory 719 String configDir = Config.getConfigDirectory().getAbsolutePath(); 720 java.io.File propConfigDir = new java.io.File(configDir, "extended-properties"); 721 if (propConfigDir.exists()) 722 { 723 // Find all XML files 724 List<java.io.File> xmlFiles = FileUtil.findFiles(propConfigDir, 725 new RegexpFileFilter(Pattern.compile(".*\\.xml"), null)); 726 if (xmlFiles != null) 727 { 728 for (java.io.File xmlFile : xmlFiles) 729 { 730 String path = xmlFile.getAbsolutePath().replace(configDir, ""); 731 files.add(path); 732 } 733 } 734 } 735 return files; 712 736 } 713 737 … … 716 740 @see RawDataTypes 717 741 */ 718 static String getRawDataTypesFile() 719 { 720 return rawDataTypesFile; 742 static List<String> getRawDataTypeFiles() 743 { 744 List<String> files = new ArrayList<String>(); 745 // Main raw data types file 746 files.add(rawDataTypesFile); 747 // Scan raw-data-types directory 748 String configDir = Config.getConfigDirectory().getAbsolutePath(); 749 java.io.File rawConfigDir = new java.io.File(configDir, "raw-data-types"); 750 if (rawConfigDir.exists()) 751 { 752 // Find all XML files 753 List<java.io.File> xmlFiles = FileUtil.findFiles(rawConfigDir, new RegexpFileFilter(Pattern.compile(".*\\.xml"), null)); 754 if (xmlFiles != null) 755 { 756 for (java.io.File xmlFile : xmlFiles) 757 { 758 String path = xmlFile.getAbsolutePath().replace(configDir, ""); 759 files.add(path); 760 } 761 } 762 } 763 return files; 721 764 } 722 765 -
trunk/src/core/net/sf/basedb/core/Config.java
r4030 r4096 27 27 import java.util.Properties; 28 28 import java.io.InputStream; 29 import java.io.IOException;30 29 import java.net.URL; 31 30 … … 50 49 private static boolean isInitialised = false; 51 50 51 private static java.io.File configDir = null; 52 52 53 /** 53 54 Loads the settings from the configuration file. … … 62 63 { 63 64 URL baseConfig = Config.class.getResource("/base.config"); 65 configDir = new java.io.File(baseConfig.toURI()).getParentFile(); 64 66 InputStream is = baseConfig == null ? null : baseConfig.openStream(); 65 67 if (is == null) … … 71 73 is.close(); 72 74 } 73 catch ( IOException ex)75 catch (Exception ex) 74 76 { 75 77 config = null; … … 86 88 isInitialised = false; 87 89 config = null; 90 configDir = null; 91 } 92 93 /** 94 Get the directory where the BASE configuration files are located. 95 @return The directory as a <code>java.io.File</code> object 96 @since 2.6 97 */ 98 public static java.io.File getConfigDirectory() 99 { 100 return configDir; 88 101 } 89 102 -
trunk/src/core/net/sf/basedb/core/ExtendedProperties.java
r3679 r4096 44 44 /** 45 45 This class is used for reading XML files with information 46 about extended properties. The file should be located at the path 47 returned by {@link Application#getExtendedPropertiesFile() 48 Application.getExtendedPropertiesFile}. 46 about extended properties. All files returned by {@link Application#getExtendedPropertyFiles()} 47 are parsed. 49 48 50 49 @see net.sf.basedb.core.data.ExtendableData … … 73 72 that class. The list holds {@link ExtendedProperty} objects. 74 73 */ 75 private static Map<String, List<ExtendedProperty>> properties = null;74 private static Map<String, List<ExtendedProperty>> allProperties = null; 76 75 77 76 /** … … 91 90 if (isInitialised) return; 92 91 classes = new ArrayList<String>(); 93 properties = new HashMap<String, List<ExtendedProperty>>();92 allProperties = new HashMap<String, List<ExtendedProperty>>(); 94 93 loadExtendedPropertiesFile(); 95 94 isInitialised = true; … … 103 102 if (classes != null) classes.clear(); 104 103 classes = null; 105 if ( properties != null) properties.clear();106 properties = null;104 if (allProperties != null) allProperties.clear(); 105 allProperties = null; 107 106 isInitialised = false; 108 107 } … … 111 110 Load and parse the file with predefined queries. 112 111 This method will populate the {@link #classes} and 113 {@link # properties} variables.112 {@link #allProperties} variables. 114 113 */ 115 114 private static synchronized void loadExtendedPropertiesFile() 116 115 throws BaseException 117 116 { 118 String propertiesFile = Application.getExtendedPropertiesFile(); 119 if (propertiesFile == null) return; 117 List<String> files = Application.getExtendedPropertyFiles(); 120 118 try 121 119 { 122 Document dom = XMLUtil.getValidatedXml(ExtendedProperties.class.getResource(propertiesFile), dtdFile); 123 loadClasses(dom); 124 log.info("Loaded extended properties from file: " + propertiesFile); 120 Set<String> usedNames = new HashSet<String>(); 121 for (String xmlFile : files) 122 { 123 Document dom = XMLUtil.getValidatedXml(ExtendedProperties.class.getResource(xmlFile), dtdFile); 124 loadClasses(usedNames, dom, xmlFile); 125 log.info("Loaded extended properties from file: " + xmlFile); 126 } 125 127 } 126 128 catch (Exception ex) … … 154 156 className = className.substring(index+1); 155 157 } 156 return properties.containsKey(className);158 return allProperties.containsKey(className); 157 159 } 158 160 … … 172 174 className = className.substring(index+1); 173 175 } 174 List<ExtendedProperty> l = (List<ExtendedProperty>) properties.get(className);176 List<ExtendedProperty> l = (List<ExtendedProperty>)allProperties.get(className); 175 177 return l; 176 178 } … … 181 183 */ 182 184 @SuppressWarnings("unchecked") 183 private static void loadClasses( Document dom)185 private static void loadClasses(Set<String> usedNames, Document dom, String xmlFile) 184 186 { 185 187 List<Element> classTags = (List<Element>)dom.getRootElement().getChildren("class"); … … 187 189 { 188 190 String className = el.getAttributeValue("name"); 189 classes.add(className); 190 properties.put(className, loadProperties(el)); 191 if (!classes.contains(className)) 192 { 193 classes.add(className); 194 allProperties.put(className, new ArrayList<ExtendedProperty>()); 195 } 196 loadProperties(usedNames, el, xmlFile); 191 197 } 192 198 } … … 194 200 /** 195 201 Load the properties for the specified class node and 196 put the list in the {@link # properties} variable.202 put the list in the {@link #allProperties} variable. 197 203 */ 198 204 @SuppressWarnings("unchecked") 199 private static List<ExtendedProperty> loadProperties(Element classElement) 200 { 201 List<ExtendedProperty> properties = new ArrayList<ExtendedProperty>(); 205 private static void loadProperties(Set<String> usedNames, Element classElement, String xmlFile) 206 { 207 String className = classElement.getAttributeValue("name"); 208 List<ExtendedProperty> properties = allProperties.get(className); 202 209 List<Element> children = (List<Element>)classElement.getChildren("property"); 203 210 DbEngine engine = HibernateUtil.getDbEngine(); 204 String className = classElement.getAttributeValue("name");205 Set<String> usedNames = new HashSet<String>();206 211 for (Element property : children) 207 212 { … … 209 214 if (!ExtendedProperty.isValidName(name)) 210 215 { 211 throw new InvalidDataException("Invalid property for class " +212 className + " : name=" + name);216 throw new InvalidDataException("Invalid property for class '" + 217 className + "' in file '" + xmlFile + "': name=" + name); 213 218 } 214 219 if (usedNames.contains("name:" + name)) 215 220 { 216 throw new InvalidDataException("Duplicate property for class " +217 className + " : name=" + name);221 throw new InvalidDataException("Duplicate property for class '" + 222 className + "' in file '" + xmlFile + "': name=" + name); 218 223 } 219 224 usedNames.add("name:" + name); … … 223 228 if (!engine.isValidColumnName(column)) 224 229 { 225 throw new InvalidDataException("Invalid column for property " +226 className + "[" + name + "] : column=" + column);230 throw new InvalidDataException("Invalid column for property '" + 231 className + "[" + name + "]' in file '" + xmlFile + "': column=" + column); 227 232 } 228 233 if (usedNames.contains("column:" + column)) 229 234 { 230 throw new InvalidDataException("Duplicate column for property " +231 className + "[" + name + "] : column=" + column);235 throw new InvalidDataException("Duplicate column for property '" + 236 className + "[" + name + "]' in file '" + xmlFile + "': column=" + column); 232 237 } 233 238 usedNames.add("column:" + column); … … 266 271 if (url == null) 267 272 { 268 throw new InvalidDataException("Missing url for property link " +269 className + "[" + name + "] : regexp=" + regexp);273 throw new InvalidDataException("Missing url for property link '" + 274 className + "[" + name + "]' in file '" + xmlFile + "': regexp=" + regexp); 270 275 } 271 276 try … … 275 280 catch (PatternSyntaxException ex) 276 281 { 277 throw new InvalidDataException("Invalid regexp for property link " +278 className + "[" + name + "] : regexp=" + regexp, ex);282 throw new InvalidDataException("Invalid regexp for property link '" + 283 className + "[" + name + "]' in file '" + xmlFile + "': regexp=" + regexp, ex); 279 284 } 280 285 } … … 282 287 properties.add(new ExtendedProperty(name, title, description, column, type, length, nullable, insertable, updateable, averageMethod, epLinks)); 283 288 } 284 return properties;285 289 } 286 290 } -
trunk/src/core/net/sf/basedb/core/RawDataTypes.java
r3867 r4096 49 49 /** 50 50 This class is used for reading the XML configuration file with 51 information about raw data types. The file should be located at the path52 returned by {@link Application#getRawDataTypesFile()}.51 information about raw data types. All files returned by {@link 52 Application#getRawDataTypeFiles()} are parsed. 53 53 54 54 @author Nicklas … … 63 63 */ 64 64 private static final org.apache.log4j.Logger log = 65 org.apache.log4j.LogManager.getLogger("net.sf.basedb.core ");65 org.apache.log4j.LogManager.getLogger("net.sf.basedb.core.RawDataTypes"); 66 66 67 67 /** … … 79 79 The DTD which is used to validate the XML file. 80 80 */ 81 private static final URL dtdFile = RawDataTypes.class.getResource("/net/sf/basedb/core/dtd/raw-data-types.dtd"); 81 private static final URL dtdFile = 82 RawDataTypes.class.getResource("/net/sf/basedb/core/dtd/raw-data-types.dtd"); 82 83 83 84 private static boolean isInitialised = false; … … 164 165 throws BaseException 165 166 { 166 String xmlFile = Application.getRawDataTypesFile(); 167 if (xmlFile == null) xmlFile = "/raw-data-types.xml"; 167 List<String> files = Application.getRawDataTypeFiles(); 168 168 try 169 169 { 170 Document dom = XMLUtil.getValidatedXml(RawDataTypes.class.getResource(xmlFile), dtdFile); 171 loadRawDataTypes(dom); 172 log.info("Loaded raw data types from file: " + xmlFile); 170 for (String xmlFile : files) 171 { 172 Document dom = XMLUtil.getValidatedXml(RawDataTypes.class.getResource(xmlFile), dtdFile); 173 loadRawDataTypes(dom, xmlFile); 174 log.info("Loaded raw data types from file: " + xmlFile); 175 } 173 176 } 174 177 catch (Exception ex) … … 287 290 */ 288 291 @SuppressWarnings({"unchecked"}) 289 private static void loadRawDataTypes(Document dom )292 private static void loadRawDataTypes(Document dom, String xmlFile) 290 293 { 291 294 List<Element> rawDataTypeTags = dom.getRootElement().getChildren("raw-data-type"); … … 303 306 if (!ExtendedProperty.isValidName(id)) 304 307 { 305 throw new InvalidDataException("Invalid id for raw data type: " + id); 308 throw new InvalidDataException("Invalid id for raw data type '" + 309 id + "' in file '" + xmlFile + "'"); 310 } 311 if (usedNames.contains("id:" + id)) 312 { 313 throw new InvalidDataException("Duplicate id for raw data type '" + 314 id +"' in file '" + xmlFile); 306 315 } 307 316 if (usedNames.contains("name:" + name)) 308 317 { 309 throw new InvalidDataException("Duplicate name for raw data type " + 310 id +": name=" + name); 311 } 318 throw new InvalidDataException("Duplicate name for raw data type '" + 319 id +"' in file '" + xmlFile + "': name=" + name); 320 } 321 usedNames.add("id:" + id); 312 322 usedNames.add("name:" + name); 313 323 if ("database".equals(storage)) … … 315 325 if (!engine.isValidTableName(table)) 316 326 { 317 throw new InvalidDataException("Invalid table for raw data type " +318 id +" : table=" + table);327 throw new InvalidDataException("Invalid table for raw data type '" + 328 id +"' in file '" + xmlFile + "': table=" + table); 319 329 } 320 330 if (usedNames.contains("table:" + table)) 321 331 { 322 throw new InvalidDataException("Duplicate table for raw data type " +323 id +": table=" + table);332 throw new InvalidDataException("Duplicate table for raw data type '" + 333 id +"' in file '" + xmlFile + "': table=" + table); 324 334 } 325 335 usedNames.add("table:" + table); … … 329 339 throw new ConfigurationException("Attribute storage='" + storage + 330 340 "' is no longer supported. Please remove declaration for <rawdatatype id='" + id + 331 "'> from " + Application.getRawDataTypesFile());341 "'> from file '" + xmlFile + "'"); 332 342 } 333 343 if (channels <= 0) 334 344 { 335 throw new InvalidDataException("Number of channels must be > 0 for raw data type "+336 id + ": channels=" + channels);337 } 338 List<RawDataProperty> properties = loadProperties(el, channels );339 List<IntensityFormula> formulas = loadIntensityFormulas(el, channels );345 throw new InvalidDataException("Number of channels must be > 0 for raw data type '"+ 346 id +"' in file '" + xmlFile + "': channels=" + channels); 347 } 348 List<RawDataProperty> properties = loadProperties(el, channels, xmlFile); 349 List<IntensityFormula> formulas = loadIntensityFormulas(el, channels, xmlFile); 340 350 RawDataType rdt = new RawDataType(id, name, description, channels, 341 351 table, properties, formulas); … … 350 360 */ 351 361 @SuppressWarnings({"unchecked"}) 352 private static List<RawDataProperty> loadProperties(Element rawDataTypeElement, int channels )362 private static List<RawDataProperty> loadProperties(Element rawDataTypeElement, int channels, String xmlFile) 353 363 { 354 364 List<RawDataProperty> properties = new ArrayList<RawDataProperty>(); … … 362 372 if (!ExtendedProperty.isValidName(name)) 363 373 { 364 throw new InvalidDataException("Invalid property for raw data type " +365 rawDataType + " : name=" + name);374 throw new InvalidDataException("Invalid property for raw data type '" + 375 rawDataType + "' in file '" + xmlFile + "': name=" + name); 366 376 } 367 377 if (usedNames.contains("name:" + name)) 368 378 { 369 throw new InvalidDataException("Duplicate property for raw data type " +370 rawDataType + " : name=" + name);379 throw new InvalidDataException("Duplicate property for raw data type '" + 380 rawDataType + "' in file '" + xmlFile + "': name=" + name); 371 381 } 372 382 usedNames.add("name:" + name); … … 376 386 if (!engine.isValidColumnName(column)) 377 387 { 378 throw new InvalidDataException("Invalid column for property" +379 rawDataType + "[" + name + "] : column=" + column);388 throw new InvalidDataException("Invalid column for raw data property '" + 389 rawDataType + "[" + name + "]' in file '" + xmlFile + "': column=" + column); 380 390 } 381 391 if (usedNames.contains("column:" + column)) 382 392 { 383 throw new InvalidDataException("Duplicate column for property" +384 rawDataType + "[" + name + "] : column=" + column);393 throw new InvalidDataException("Duplicate column for raw data property '" + 394 rawDataType + "[" + name + "]' in file '" + xmlFile + "': column=" + column); 385 395 } 386 396 usedNames.add("column:" + column); … … 408 418 if (channel < 0 || channel > channels) 409 419 { 410 throw new InvalidDataException("Channel for property " + rawDataType+ "[" + name + "]" 411 + " must be >= 0 and < " + channels + ": channel=" + channel); 420 throw new InvalidDataException("Channel for raw data property '" + 421 rawDataType+ "[" + name + "]' in file '" + xmlFile + "'" + 422 " must be >= 0 and < " + channels + ": channel=" + channel); 412 423 } 413 424 properties.add(new RawDataProperty(name, title, description, column, type, length, nullable, averageMethod, channel)); … … 421 432 */ 422 433 @SuppressWarnings({"unchecked"}) 423 private static List<IntensityFormula> loadIntensityFormulas(Element rawDataTypeElement, int channels )434 private static List<IntensityFormula> loadIntensityFormulas(Element rawDataTypeElement, int channels, String xmlFile) 424 435 { 425 436 List<IntensityFormula> formulas = new ArrayList<IntensityFormula>(); … … 432 443 if (!ExtendedProperty.isValidName(name)) 433 444 { 434 throw new InvalidDataException("Invalid intensity formula for raw data type " +435 rawDataType + " : name=" + name);445 throw new InvalidDataException("Invalid intensity formula for raw data type '" + 446 rawDataType + "' in file '" + xmlFile + "': name=" + name); 436 447 } 437 448 if (usedNames.contains("name:" + name)) 438 449 { 439 throw new InvalidDataException("Duplicate intensity formula for raw data type " +440 rawDataType + " : name=" + name);450 throw new InvalidDataException("Duplicate intensity formula for raw data type '" + 451 rawDataType + "' in file '" + xmlFile + "': name=" + name); 441 452 } 442 453 usedNames.add("name:" + name); … … 451 462 if (channel <= 0 || channel > channels) 452 463 { 453 throw new InvalidDataException("Channel for intensity formula " +454 rawDataType+ "[" + name + "] "455 +" must be > 0 and < " + channels + ": channel=" + channel);464 throw new InvalidDataException("Channel for intensity formula '" + 465 rawDataType+ "[" + name + "]' in file '" + xmlFile + "'" + 466 " must be > 0 and < " + channels + ": channel=" + channel); 456 467 } 457 468 if (expressions[channel-1] != null) 458 469 { 459 throw new InvalidDataException("Duplicate expression for intensity formula " +460 rawDataType + "[" + name + "] : channel=" + channel);470 throw new InvalidDataException("Duplicate expression for intensity formula '" + 471 rawDataType + "[" + name + "]' in file '" + xmlFile + "': channel=" + channel); 461 472 } 462 473 if (exp == null) 463 474 { 464 throw new InvalidDataException("Missing expression for formula " +465 rawDataType + "[" + name + "] : channel=" + channel);475 throw new InvalidDataException("Missing expression for formula '" + 476 rawDataType + "[" + name + "]' in file '" + xmlFile + "': channel=" + channel); 466 477 } 467 478 expressions[channel-1] = exp;
Note: See TracChangeset
for help on using the changeset viewer.