Changeset 6684
- Timestamp:
- Jan 14, 2015, 2:29:04 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 38 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/3.4-stable (added) merged: 6643,6645-6651,6659-6681 /tags/3.4.0 (added) merged: 6682
- Property svn:mergeinfo changed
-
trunk/build.xml
r6644 r6684 486 486 <fileset dir="${core.src}" includes="**/*.hbm.xml" /> 487 487 </copy> 488 <copy todir="${build}/hbm" 489 description="Copy our data class files so xdoclet doesn't parse other code"> 490 <fileset dir="${core.src}" includes="net/sf/basedb/core/data/**/*" /> 491 </copy> 492 488 493 <hibernatedoclet 489 494 destdir="${core.build}" 490 495 excludedtags="@version,@author,@todo" 491 496 mergedir="${core.build}" 492 verbose="${xdoclet.verbose}"> 493 <fileset dir="${core.src}"> 497 verbose="true" 498 > 499 <fileset dir="${build}/hbm"> 494 500 <include name="net/sf/basedb/core/data/**/*.java"/> 495 501 </fileset> 496 <hibernate version="2.0" />502 <hibernate version="2.0" /> 497 503 </hibernatedoclet> 498 504 -
trunk/doc/src/docbook/admin/installation.xml
r6479 r6684 565 565 566 566 <para> 567 The second command is important for PostgreSQL users since 568 the Hibernate database initialisation utility is not able 569 to create all required indexes. BASE will work without the 570 indexes but performance is impaired. Running the script as 571 a MySQL user does not have a negative impact. 567 The second command is important since 568 the Hibernate database initialisation utility is not always 569 able to create all required indexes. In some cases, Hibernate 570 will also create a new index, even if one already exists. 571 The command ensures that missing indexes are created and 572 that duplicates are removed. BASE will work without the 573 indexes but performance is impaired. 572 574 </para> 573 575 -
trunk/src/clients/web/net/sf/basedb/clients/web/extensions/skin/FixedSkinActionFactory.java
r6632 r6684 22 22 package net.sf.basedb.clients.web.extensions.skin; 23 23 24 import java.util.Iterator; 25 24 26 import net.sf.basedb.clients.web.extensions.AbstractJspActionFactory; 27 import net.sf.basedb.clients.web.extensions.DynamicActionAttribute; 28 import net.sf.basedb.clients.web.extensions.DynamicActionAttributes; 25 29 import net.sf.basedb.clients.web.extensions.ExtensionsControl; 26 30 import net.sf.basedb.util.extensions.InvokationContext; … … 103 107 104 108 static class MySkinAction 105 implements SkinAction 109 implements SkinAction, DynamicActionAttributes 106 110 { 107 111 private final FixedSkinActionFactory factory; … … 136 140 } 137 141 142 @Override 143 public Iterator<DynamicActionAttribute> getDynamicActionAttributes() 144 { 145 return factory.getDynamicActionAttributes(); 146 } 138 147 139 148 } -
trunk/src/clients/web/net/sf/basedb/clients/web/taglib/Page.java
r6632 r6684 174 174 175 175 /** 176 Set to TRUE to not use skin on the page. 177 @since 3.4 178 */ 179 private boolean noSkin = false; 180 181 /** 176 182 The <!doctype xxx> setting. 177 183 */ … … 253 259 return title; 254 260 } 255 261 262 /** 263 Set to TRUE to disable skins. 264 @since 3.4 265 */ 266 public void setNoskin(boolean noSkin) 267 { 268 this.noSkin = noSkin; 269 } 270 271 public boolean getNoSkin() 272 { 273 return noSkin; 274 } 275 256 276 public void setType(String type) 257 277 { … … 335 355 public JspContext getSkinContext() 336 356 { 337 return skinContext;357 return noSkin ? null : skinContext; 338 358 } 339 359 … … 345 365 public List<SkinAction> getSkinActions() 346 366 { 347 return skinActions;367 return noSkin ? null : skinActions; 348 368 } 349 369 … … 369 389 if (type != PAGE_TYPE_INCLUDE) 370 390 { 371 // Load skin extensions: net.sf.basedb.clients.web.global-skin 372 skinContext = ExtensionsControl.createContext(sc, pageContext); 373 skinContext.setAttribute("page-type", getTypeCode()); 374 ExtensionsInvoker<SkinAction> invoker = (ExtensionsInvoker<SkinAction>)ExtensionsControl.useExtensions(skinContext, "net.sf.basedb.clients.web.global-skin"); 375 ActionIterator<SkinAction> it = invoker.iterate(); 376 skinActions = new ArrayList<SkinAction>(); 377 ImageRemapper remapper = ImageRemapperUtil.getNewImageRemapperIfNeeded(pageContext.getServletContext()); 378 while (it.hasNext()) 391 if (!noSkin) 379 392 { 380 SkinAction skin = it.next(); 381 if (remapper != null) skin.remapImages(remapper); 382 skinActions.add(skin); 383 if (favicon == null) 393 // Load skin extensions: net.sf.basedb.clients.web.global-skin 394 skinContext = ExtensionsControl.createContext(sc, pageContext); 395 skinContext.setAttribute("page-type", getTypeCode()); 396 ExtensionsInvoker<SkinAction> invoker = (ExtensionsInvoker<SkinAction>)ExtensionsControl.useExtensions(skinContext, "net.sf.basedb.clients.web.global-skin"); 397 ActionIterator<SkinAction> it = invoker.iterate(); 398 skinActions = new ArrayList<SkinAction>(); 399 ImageRemapper remapper = ImageRemapperUtil.getNewImageRemapperIfNeeded(pageContext.getServletContext()); 400 while (it.hasNext()) 384 401 { 385 String skinIcon = skin.getFavicon(); 386 if (skinIcon != null) favicon = skinIcon; 402 SkinAction skin = it.next(); 403 if (remapper != null) skin.remapImages(remapper); 404 skinActions.add(skin); 405 if (favicon == null) 406 { 407 String skinIcon = skin.getFavicon(); 408 if (skinIcon != null) favicon = skinIcon; 409 } 387 410 } 411 if (remapper != null) ImageRemapperUtil.setCurrentMapper(remapper); 388 412 } 389 if (remapper != null) ImageRemapperUtil.setCurrentMapper(remapper);390 413 391 414 StringBuilder sb = new StringBuilder(); -
trunk/src/core/net/sf/basedb/core/AnyToAny.java
r6127 r6684 28 28 import org.hibernate.mapping.Table; 29 29 30 import net.sf.basedb.core.Transactional.Action;31 30 import net.sf.basedb.core.data.AnyToAnyData; 32 31 import net.sf.basedb.core.hibernate.TypeWrapper; … … 52 51 public class AnyToAny 53 52 extends BasicItem<AnyToAnyData> 54 implements Nameable 53 implements Nameable, Transactional 55 54 { 56 55 … … 480 479 { 481 480 super.onBeforeCommit(action); 482 if (action == Action.CREATE )481 if (action == Action.CREATE || action == Action.UPDATE && (getToId() == 0 || getFromId() == 0)) 483 482 { 484 483 // In case either the to or from items are also new items -
trunk/src/core/net/sf/basedb/core/DbControl.java
r6576 r6684 41 41 import net.sf.basedb.util.extensions.manager.ExtensionsManager; 42 42 43 import java.util.HashSet; 43 44 import java.util.IdentityHashMap; 44 45 import java.util.Iterator; … … 49 50 import java.util.HashMap; 50 51 import java.util.LinkedHashMap; 52 import java.util.Set; 51 53 import java.lang.reflect.Constructor; 52 54 … … 146 148 147 149 /** 150 Holds random strings that must be unique within a transaction. 151 */ 152 private Set<String> uniqueRandoms; 153 154 /** 148 155 Create a new object. 149 156 */ … … 169 176 itemCache = new IdentityHashMap<BasicData, BasicItem>(); 170 177 commitQueue = new LinkedHashMap<BasicItem,Transactional.Action>(); 178 uniqueRandoms = new HashSet<String>(); 171 179 isClosed = false; 172 180 isConnected = true; … … 376 384 commitQueue.clear(); 377 385 itemCache.clear(); 386 uniqueRandoms.clear(); 378 387 if (batchers != null) batchers.clear(); 379 388 if (saveIfQueue != null) saveIfQueue.clear(); … … 383 392 transactionalActions = null; 384 393 itemCache = null; 394 uniqueRandoms = null; 385 395 batchers = null; 386 396 isClosed = true; … … 1211 1221 1212 1222 /** 1223 Generate a random string value that is unique for the given transaction. 1224 @since 3.4 1225 */ 1226 public String uniqueRandom() 1227 { 1228 String random = null; 1229 while (true) 1230 { 1231 random = Application.generateRandomId(4); 1232 if (uniqueRandoms.add(random)) break; 1233 } 1234 return random; 1235 } 1236 1237 /** 1213 1238 Add a <code>Batcher</code> to the batcher queue. 1214 1239 @param batcher The <code>Batcher</code> to add -
trunk/src/core/net/sf/basedb/core/HibernateUtil.java
r6631 r6684 40 40 import net.sf.basedb.core.dbengine.TableInfo.ForeignKeyInfo; 41 41 import net.sf.basedb.core.dbengine.TableInfo.IndexInfo; 42 import net.sf.basedb.core.hibernate.DbIndexWork; 42 43 import net.sf.basedb.core.hibernate.EntityQueryWrapper; 43 44 import net.sf.basedb.core.hibernate.ExecuteUpdateWork; … … 640 641 } 641 642 642 if (mode.requireEmptyDatabase()) 643 { 644 if (!isEmptyDatabase()) 645 { 646 throw new BaseException("Database already has tables."); 647 } 643 boolean emptyDatabase = isEmptyDatabase(); 644 if (mode.requireEmptyDatabase() && !emptyDatabase) 645 { 646 throw new BaseException("Database already has tables."); 647 } 648 else if (!mode.requireEmptyDatabase() && emptyDatabase) 649 { 650 throw new BaseException("Database is empty"); 648 651 } 649 652 … … 700 703 { 701 704 isEmpty = false; 702 log.error("Table '"+t.getName()+"' already exists; install aborted"); 705 log.debug("Table '"+t.getName()+"' already exists"); 706 } 707 else 708 { 709 log.debug("Table '"+t.getName()+"' doesn't exists"); 703 710 } 704 711 tables.close(); … … 1252 1259 try 1253 1260 { 1254 session.close();1261 if (session.isOpen()) session.close(); 1255 1262 } 1256 1263 catch(HibernateException ex) … … 2204 2211 final boolean dropIndexes, final boolean updateIndexes) 2205 2212 { 2206 final boolean isVerbose = verbose && !silent;2207 2213 Session session = newSession(); 2208 2209 try 2210 { 2211 HibernateUtil.doWork(session, 2212 new Work() 2213 { 2214 @Override 2215 public void execute(Connection connection) 2216 throws SQLException 2217 { 2218 Iterator<Table> tables = (Iterator<Table>)cfg.getTableMappings(); 2219 DatabaseMetaData metaData = connection.getMetaData(); 2220 while (tables.hasNext()) 2221 { 2222 Table table = tables.next(); 2223 if (!silent) 2224 { 2225 System.out.println("================="); 2226 System.out.println("Table : " + table.getName()); 2227 } 2228 if (isVerbose) 2229 { 2230 System.out.println("Catalog : " + table.getCatalog()); 2231 System.out.println("Schema : " + table.getSchema()); 2232 } 2233 2234 if (isVerbose) 2235 { 2236 System.out.println("Database information"); 2237 System.out.println("--------------------"); 2238 } 2239 2240 TableInfo tiDb = null; 2241 try 2242 { 2243 tiDb = new TableInfo(table, metaData); 2244 } 2245 catch (SQLException ex) 2246 { 2247 throw new BaseException(ex); 2248 } 2249 2250 if (isVerbose && tiDb != null) 2251 { 2252 // Write all columns 2253 for (ColumnInfo ci : tiDb.getColumns()) 2254 { 2255 System.out.println(" Column : " + ci); 2256 } 2257 2258 // Write primary key 2259 System.out.println(" Primary key : " + tiDb.getPrimaryKey()); 2260 2261 // Write foreign keys 2262 for (ForeignKeyInfo fk : tiDb.getForeignKeys()) 2263 { 2264 System.out.println(" Foreign key : " + fk); 2265 } 2266 2267 // Write indexes and unique constraints 2268 for (IndexInfo ii : tiDb.getIndexes()) 2269 { 2270 if (ii.isUnique()) 2271 { 2272 System.out.println(" Unique : " + ii); 2273 } 2274 else 2275 { 2276 System.out.println(" Index : " + ii); 2277 } 2278 } 2279 } 2280 2281 if (isVerbose) 2282 { 2283 System.out.println("Hibernate information"); 2284 System.out.println("---------------------"); 2285 } 2286 2287 TableInfo tiHib = new TableInfo(table, dialect); 2288 if (isVerbose) 2289 { 2290 // Write all columns 2291 for (ColumnInfo ci : tiHib.getColumns()) 2292 { 2293 System.out.println(" Column : " + ci); 2294 } 2295 2296 // Write primary key 2297 System.out.println(" Primary key : " + tiHib.getPrimaryKey()); 2298 } 2299 2300 // Write foreign keys 2301 for (ForeignKeyInfo fk : tiHib.getForeignKeys()) 2302 { 2303 if (!silent) 2304 { 2305 System.out.println(" Foreign key : " + fk); 2306 } 2307 2308 // Check that an index for the foreign key exists 2309 String indexName = tiDb.findIndexName(fk.getName(), fk.getFkColumns()); 2310 boolean indexExists = indexName != null; 2311 String createSql = 2312 dbEngine.getCreateIndexSql(table.getCatalog(), table.getSchema(), 2313 table.getName(), fk.getName(), fk.getFkColumns(), false); 2314 boolean actionCreate = updateIndexes && !indexExists; 2315 2316 if (!silent) 2317 { 2318 System.out.println(" Indexed : " + indexExists + (indexExists ? "(" + indexName + ")" : "")); 2319 System.out.println(" INDEX-SQL : " + createSql); 2320 System.out.println(" Actions : " + (actionCreate ? "CREATE INDEX" : "")); 2321 } 2322 if (actionCreate) 2323 { 2324 Statement st = null; 2325 try 2326 { 2327 st = connection.createStatement(); 2328 if (actionCreate) 2329 { 2330 log.info("Creating foreign key index: + " + createSql); 2331 st.executeUpdate(createSql); 2332 } 2333 connection.commit(); 2334 st.close(); 2335 st = null; 2336 } 2337 catch (SQLException ex) 2338 { 2339 log.error("Exception", ex); 2340 throw new BaseException(ex); 2341 } 2342 finally 2343 { 2344 if (st != null) 2345 { 2346 try 2347 { 2348 st.close(); 2349 } 2350 catch (Throwable t) 2351 { 2352 log.error("Exception", t); 2353 } 2354 } 2355 } 2356 } 2357 } 2358 2359 // Write indexes and unique constraints 2360 for (IndexInfo ii : tiHib.getIndexes()) 2361 { 2362 if (!silent) 2363 { 2364 if (ii.isUnique()) 2365 { 2366 System.out.println(" Unique : " + ii); 2367 } 2368 else 2369 { 2370 System.out.println(" Index : " + ii); 2371 } 2372 } 2373 2374 String dbName = tiDb.findIndexName(ii.getName(), ii.getColumns()); 2375 boolean exists = dbName != null; 2376 boolean safeToDrop = exists && tiDb.safeToDrop(ii); 2377 2378 String dropSql = exists ? 2379 dbEngine.getDropIndexSql(table.getCatalog(), table.getSchema(), 2380 table.getName(), dbName, ii.isUnique()) : ""; 2381 String createSql = 2382 dbEngine.getCreateIndexSql(table.getCatalog(), table.getSchema(), 2383 table.getName(), table.getName() + "_" + ii.getName(), 2384 ii.getColumns(), ii.isUnique()); 2385 boolean actionDrop = dropIndexes && exists && safeToDrop; 2386 boolean actionCreate = updateIndexes && (actionDrop || !exists); 2387 2388 if (!silent) 2389 { 2390 System.out.println(" Exists : " + exists + (exists ? "(" + dbName + ")" : "")); 2391 System.out.println(" Safe drop : " + safeToDrop); 2392 System.out.println(" DROP-SQL : " + dropSql); 2393 System.out.println(" CREATE-SQL : " + createSql); 2394 System.out.println(" Actions : " + (actionDrop ? "DROP " : "") + 2395 (actionCreate ? "CREATE" : "")); 2396 } 2397 if (actionDrop || actionCreate) 2398 { 2399 Statement st = null; 2400 try 2401 { 2402 st = connection.createStatement(); 2403 if (actionDrop) 2404 { 2405 log.info("Dropping index: + " + dropSql); 2406 st.executeUpdate(dropSql); 2407 } 2408 if (actionCreate) 2409 { 2410 log.info("Creating index: + " + createSql); 2411 st.executeUpdate(createSql); 2412 } 2413 connection.commit(); 2414 st.close(); 2415 st = null; 2416 } 2417 catch (SQLException ex) 2418 { 2419 log.error("Exception", ex); 2420 throw new BaseException(ex); 2421 } 2422 finally 2423 { 2424 if (st != null) 2425 { 2426 try 2427 { 2428 st.close(); 2429 } 2430 catch (Throwable t) 2431 { 2432 log.error("Exception", t); 2433 } 2434 } 2435 } 2436 } 2437 2438 } 2439 2440 if (!silent) 2441 { 2442 System.out.println("================="); 2443 System.out.println(""); 2444 } 2445 } 2446 2447 } 2448 2449 } 2450 ); 2214 try 2215 { 2216 HibernateUtil.doWork(session, new DbIndexWork(cfg, dialect, dbEngine, verbose, silent, dropIndexes, updateIndexes)); 2451 2217 } 2452 2218 catch (SQLException ex) 2453 { 2454 2455 } 2456 2219 {} 2457 2220 } 2458 2221 -
trunk/src/core/net/sf/basedb/core/ItemContext.java
r6336 r6684 1720 1720 // propertyDef is JEP expression 1721 1721 Expression e = Jep.formulaToExpression(propertyDef.substring(1), ch, rawCh, raw, rep, mrep); 1722 s = Selects.expression(e, "jep" + System.identityHashCode(e));1722 s = Selects.expression(e, "jep" + dc.uniqueRandom()); 1723 1723 } 1724 1724 else -
trunk/src/core/net/sf/basedb/core/PropertyFilter.java
r6214 r6684 515 515 if (obj != null) 516 516 { 517 String parameterName = "p" + System.identityHashCode(obj);517 String parameterName = "p" + dc.uniqueRandom(); 518 518 Type theValueType = obj instanceof Double ? Type.DOUBLE : getValueType(); 519 519 if (theValueType == Type.TIMESTAMP) theValueType = Type.DATE; … … 526 526 else 527 527 { 528 String parameterName = "p" + System.identityHashCode(this);528 String parameterName = "p" + dc.uniqueRandom(); 529 529 Expression parameter = null; 530 530 if (getValue() != null) … … 605 605 else 606 606 { 607 String parameterName = "p" + System.identityHashCode(this);607 String parameterName = "p" + dc.uniqueRandom(); 608 608 Expression parameter = null; 609 609 if (getValue() != null && !operator.isListOperator()) … … 632 632 if (obj != null) 633 633 { 634 parameterName = "p" + System.identityHashCode(obj);634 parameterName = "p" + dc.uniqueRandom(); 635 635 Type theValueType = obj instanceof Double ? Type.DOUBLE : getValueType(); 636 636 Expression e = Expressions.parameter(parameterName, obj, theValueType); … … 674 674 String entityCollection = m.group(1); 675 675 String collectionFilter = m.group(2); 676 boolean rewriteNullFilter = false; 677 if (collectionFilter.startsWith("%")) 678 { 679 collectionFilter = collectionFilter.substring(1); 680 rewriteNullFilter = true; 681 } 676 682 677 683 /* … … 732 738 } 733 739 740 boolean notContains = subfilterOperator != operator; 741 Operator actualOperator = subfilterOperator; 742 String actualValue = getValue(); 743 if (rewriteNullFilter && actualValue == null && subfilterOperator == Operator.EQ) 744 { 745 // =ANY(... WHERE <property> IS NULL) is rewritten as 746 // <>ALL(... WHERE <property> LIKE '%') 747 actualOperator = Operator.LIKE; 748 actualValue = "%"; 749 notContains = !notContains; 750 } 751 734 752 // Restrict the subquery 735 753 PropertyFilter pp = new PropertyFilter("$" + thisAlias + "." + collectionFilter, 736 subfilterOperator, getValue(), getValueType());754 actualOperator, actualValue, getValueType()); 737 755 subquery.restrict(pp.getRestriction(dc, query)); 738 756 739 757 // Create the main restriction 740 if ( subfilterOperator != operator)758 if (notContains) 741 759 { 742 760 // "not contains": root-entity <> ALL(subquery) … … 807 825 if (obj != null) 808 826 { 809 parameterName = "p" + System.identityHashCode(obj);827 parameterName = "p" + dc.uniqueRandom(); 810 828 Type theValueType = obj instanceof Double ? Type.DOUBLE : getValueType(); 811 829 if (theValueType == Type.TIMESTAMP) theValueType = Type.DATE; … … 859 877 propertyExpression = ItemContext.getDynamicExpression(dc, property); 860 878 } 861 String parameterName = "p" + System.identityHashCode(this);879 String parameterName = "p" + dc.uniqueRandom(); 862 880 863 881 String value = getValue(); … … 900 918 if (obj != null) 901 919 { 902 parameterName = "p" + System.identityHashCode(obj);920 parameterName = "p" + dc.uniqueRandom(); 903 921 e = Expressions.parameter(parameterName, obj); 904 922 } -
trunk/src/core/net/sf/basedb/core/RawDataTypes.java
r6473 r6684 161 161 { 162 162 List<String> files = Application.getRawDataTypeFiles(); 163 Set<String> usedNames = new HashSet<String>(); 163 164 try 164 165 { … … 166 167 { 167 168 Document dom = XmlUtil2.getValidatedXml(RawDataTypes.class.getResource(xmlFile), dtdFile); 168 loadRawDataTypes( dom, xmlFile);169 loadRawDataTypes(usedNames, dom, xmlFile); 169 170 log.info("Loaded raw data types from file: " + xmlFile); 170 171 } … … 334 335 {@link #rawDataTypes} map. 335 336 */ 336 private static void loadRawDataTypes( Document dom, String xmlFile)337 private static void loadRawDataTypes(Set<String> usedNames, Document dom, String xmlFile) 337 338 { 338 339 List<Element> rawDataTypeTags = dom.getRootElement().getChildren("raw-data-type"); 339 340 DbEngine engine = HibernateUtil.getDbEngine(); 340 Set<String> usedNames = new HashSet<String>();341 341 for (Element el : rawDataTypeTags) 342 342 { -
trunk/src/core/net/sf/basedb/core/ServiceSessionControl.java
r6631 r6684 31 31 import net.sf.basedb.core.data.UserData; 32 32 import net.sf.basedb.core.dbengine.DbEngine; 33 import net.sf.basedb.core.hibernate.DbIndexWork; 33 34 import net.sf.basedb.core.hibernate.GetCurrentCatalogWork; 34 35 import net.sf.basedb.core.hibernate.SchemaExistsWork; … … 44 45 import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 45 46 import org.hibernate.cfg.Configuration; 47 import org.hibernate.dialect.Dialect; 46 48 import org.hibernate.service.ServiceRegistry; 47 49 … … 138 140 // but MySQL don't have schemas so actual catalog is a combined of both 139 141 DbEngine dbEngine = HibernateUtil.getDbEngine(); 142 Dialect dialect = HibernateUtil.getDialect(); 140 143 String actualCatalog = dbEngine.getCatalogName(catalog, schema); 141 144 String actualSchema = dbEngine.getSchemaName(catalog, schema); 142 145 143 if (log.isDebugEnabled()) log.debug("Actual catalog/schema: " + actualCatalog + "/" + actualSchema); 144 146 if (log.isDebugEnabled()) log.debug("Actual catalog/schema: " + actualCatalog + "/" + actualSchema); 145 147 if (actualCatalog != null) 146 148 { … … 188 190 if (mode != null) 189 191 { 192 // Generates tables and most other things 190 193 SchemaGenerator schemaGenerator = 191 new SchemaGenerator(cfg, HibernateUtil.getDialect(), dbEngine, mode, null);194 new SchemaGenerator(cfg, dialect, dbEngine, mode, null); 192 195 session.doWork(schemaGenerator); 196 // Generates missing indexes 197 DbIndexWork indexGenerator = new DbIndexWork(cfg, dialect, dbEngine, false, true, false, true); 198 session.doWork(indexGenerator); 199 // Update schema version in BASE 193 200 if (config.getAppId() != null) 194 201 { … … 196 203 } 197 204 HibernateUtil.commit(tx); 205 tx = null; 198 206 } 199 207 … … 228 236 /** 229 237 Create a new Hibernate session for the given session factory that 230 is piggy-backed on the given DbControl transaction. 238 is piggy-backed on the given DbControl transaction. 239 240 Note that the life-cycle of the returned session is managed by the 241 DbControl. There is no need to flush or close the session since this 242 is done automatically and may cause exceptions if done when not needed. 231 243 232 244 @param A session builder (eg. SessionFactory.withOptions()) -
trunk/src/core/net/sf/basedb/core/data/ExtractData.java
r6279 r6684 75 75 } 76 76 77 private Set<DerivedBioAssayData> derivedBioAssays; 78 /** 79 This is the inverse end. 80 @see DerivedBioAssayData#getExtract() 81 @since 3.4 82 @hibernate.set lazy="true" inverse="true" 83 @hibernate.collection-key column="`extract_id`" 84 @hibernate.collection-one-to-many class="net.sf.basedb.core.data.DerivedBioAssayData" 85 */ 86 Set<DerivedBioAssayData> getDerivedBioAssays() 87 { 88 return derivedBioAssays; 89 } 90 void setDerivedBioAssays(Set<DerivedBioAssayData> derivedBioAssays) 91 { 92 this.derivedBioAssays = derivedBioAssays; 93 } 94 77 95 } -
trunk/src/core/net/sf/basedb/core/dbengine/MySQLEngine.java
r6630 r6684 27 27 import java.util.regex.Pattern; 28 28 29 import net.sf.basedb.core.hibernate.SchemaGenerator; 30 31 import org.hibernate.dialect.Dialect; 29 32 import org.hibernate.mapping.PersistentClass; 30 33 … … 211 214 212 215 /** 216 Fix "alter table ... drop constraint ..." statements that are generated 217 incorrectly by Hibernate. 218 @since 3.4 219 */ 220 @Override 221 public String inspectSchemaGenerationSQL(String sql, Dialect dialect, 222 SchemaGenerator.Mode mode) 223 { 224 sql = super.inspectSchemaGenerationSQL(sql, dialect, mode); 225 if (sql != null && sql.startsWith("alter table") && sql.contains("drop constraint")) 226 { 227 sql = sql.replace("drop constraint", "drop index"); 228 } 229 return sql; 230 } 231 232 233 /** 213 234 Return true. 214 235 */ -
trunk/src/core/net/sf/basedb/core/dbengine/PostgresDbEngine.java
r6630 r6684 77 77 Generate <code>ALTER TABLE <schema>.<table> ADD CONSTRAINT <name> 78 78 UNIQUE (<columns>)</code> for a unique index, 79 <code>CREATE INDEX < schema>.<name> ON <schema>.<table> (<columns>)</code>79 <code>CREATE INDEX <name> ON <schema>.<table> (<columns>)</code> 80 80 for other indexes. 81 81 The catalog parameter is not supported. … … 98 98 { 99 99 sql.append("CREATE INDEX "); 100 if (schema != null) sql.append(getQuotedName(schema)).append(".");101 100 sql.append(getQuotedName(name)).append(" ON "); 102 101 if (schema != null) sql.append(getQuotedName(schema)).append("."); -
trunk/src/core/net/sf/basedb/core/dbengine/TableInfo.java
r6127 r6684 28 28 import java.sql.Statement; 29 29 import java.sql.Types; 30 import java.util.ArrayList; 30 31 import java.util.Arrays; 31 32 import java.util.Collections; … … 115 116 } 116 117 118 117 119 /** 118 120 Create table info by reading JDBC metadata from the current database … … 123 125 */ 124 126 public TableInfo(Table table, DatabaseMetaData metaData) 127 throws SQLException 128 { 129 this(table, metaData, null, null); 130 } 131 132 /** 133 Create table info by reading JDBC metadata from the current database 134 135 @param table The Hibernate table object 136 @param metaData The JDBC metadata connected to the current database 137 @param defaultCatalog Catalog to use if the table doesn't specify a catalog 138 @param defaultSchema Schema to use if the table doesn't specify a catalog 139 @throws SQLException If there is an error 140 @since 3.4 141 */ 142 public TableInfo(Table table, DatabaseMetaData metaData, String defaultCatalog, String defaultSchema) 125 143 throws SQLException 126 144 { 127 145 this(table); 128 146 129 ResultSet tables = metaData.getTables(table.getCatalog(), table.getSchema(), table.getName(), null); 147 String catalog = table.getCatalog(); 148 if (catalog == null) catalog = defaultCatalog; 149 String schema = table.getSchema(); 150 if (schema == null) schema = defaultSchema; 151 152 ResultSet tables = metaData.getTables(catalog, schema, table.getName(), null); 130 153 existsInDb = tables.next(); 131 154 tables.close(); 132 133 155 if (!existsInDb) return; 134 156 135 157 // Load column information 136 ResultSet sqlColumns = metaData.getColumns( table.getCatalog(), table.getSchema(), table.getName(), "%");158 ResultSet sqlColumns = metaData.getColumns(catalog, schema, table.getName(), "%"); 137 159 while (sqlColumns.next()) 138 160 { … … 147 169 148 170 // Load primary key information 149 ResultSet sqlPK = metaData.getPrimaryKeys( table.getCatalog(), table.getSchema(), table.getName());171 ResultSet sqlPK = metaData.getPrimaryKeys(catalog, schema, table.getName()); 150 172 Set<String> pkColumns = new LinkedHashSet<String>(); 151 173 String pkName = null; … … 162 184 163 185 // Load foreign keys 164 ResultSet sqlFK = metaData.getImportedKeys( table.getCatalog(), table.getSchema(), table.getName());186 ResultSet sqlFK = metaData.getImportedKeys(catalog, schema, table.getName()); 165 187 Map<String, ForeignKeyInfo> fkInfo = new HashMap<String, ForeignKeyInfo>(); 166 188 while (sqlFK.next()) … … 184 206 185 207 // Load indexes 186 ResultSet sqlIndexes = metaData.getIndexInfo( table.getCatalog(), table.getSchema(), table.getName(), false, true);208 ResultSet sqlIndexes = metaData.getIndexInfo(catalog, schema, table.getName(), false, true); 187 209 Map<String, IndexInfo> indexInfo = new HashMap<String, IndexInfo>(); 188 210 while (sqlIndexes.next()) … … 191 213 String column = makeSafe(sqlIndexes.getString("COLUMN_NAME")); 192 214 boolean isUnique = !sqlIndexes.getBoolean("NON_UNIQUE"); 193 194 215 IndexInfo ii = indexInfo.get(indexName); 195 216 if (ii == null) … … 441 462 } 442 463 return null; 464 } 465 466 /** 467 Find all indexes with the given set of columns. Used for 468 getting rid of duplicates. 469 @param columns A set containing the column names that should be present in 470 the index 471 @return A list with the index information or an empty list of no index is found 472 @since 3.4 473 */ 474 public List<IndexInfo> findAll(Set<String> columns) 475 { 476 List<IndexInfo> all = new ArrayList<IndexInfo>(); 477 for (IndexInfo iiInfo : indexes) 478 { 479 if (columns.equals(iiInfo.getColumns())) all.add(iiInfo); 480 } 481 return all; 443 482 } 444 483 -
trunk/src/core/net/sf/basedb/core/hibernate/SchemaGenerator.java
r6468 r6684 120 120 int numDone = 0; 121 121 int interval = Math.max(1, numStatements / 30); 122 122 123 for (SchemaUpdateScript script : allSql) 123 124 { … … 131 132 } 132 133 log.debug("Executing: " + actualSql); 133 stmt.executeUpdate(actualSql); 134 //System.out.println(actualSql); 134 try 135 { 136 stmt.executeUpdate(actualSql); 137 } 138 catch (SQLException | RuntimeException ex) 139 { 140 if (script.isQuiet()) 141 { 142 log.info("Ignoring quiet SQL: "+ actualSql, ex); 143 } 144 else 145 { 146 throw ex; 147 } 148 } 135 149 if (progress != null) 136 150 { … … 153 167 } 154 168 } 155 catch (SQLException ex)169 catch (SQLException | RuntimeException ex) 156 170 { 157 171 log.error("Schema update failed", ex); -
trunk/src/core/net/sf/basedb/core/signal/AbstractSignalReceiver.java
r6444 r6684 28 28 import java.util.HashMap; 29 29 import java.util.Map; 30 import java.util.WeakHashMap; 31 32 import net.sf.basedb.core.Application; 30 33 31 34 /** … … 76 79 */ 77 80 private Map<String, SignalHandler> handlers; 81 private Map<SignalHandler, String> handlerIds; 78 82 private String receiverId; 79 83 private Thread notifyThread; … … 98 102 { 99 103 handlers = Collections.synchronizedMap(new HashMap<String, SignalHandler>()); 104 handlerIds = new WeakHashMap<SignalHandler, String>(); 100 105 this.receiverId = receiverId; 101 106 logger.info("Initializing signal receiver: id=" + receiverId); … … 165 170 { 166 171 if (notifyThread != null) throw new SignalException("Signal receiver is shutting down."); 172 String localId = getLocalSignalHandlerId(handler); 167 173 String globalId = getGlobalSignalId(handler); 168 String localId = getLocalSignalHandlerId(handler);169 174 if (handlers != null) 170 175 { 171 if (handlers.containsKey(localId)) 172 { 173 throw new SignalException("A handler with ID '" + localId + "' is already registered: " 174 + handlers.get(localId)); 175 } 176 handlers.put(localId, handler); 176 synchronized (handlers) 177 { 178 if (handlers.containsKey(localId)) 179 { 180 throw new SignalException("A handler with ID '" + localId + "' is already registered: " 181 + handlers.get(localId)); 182 } 183 handlers.put(localId, handler); 184 } 177 185 } 178 186 … … 180 188 "; global id=" + globalId + "; local id=" + localId); 181 189 logger.debug("Current number of registered signal handlers: " + 182 (handlers == null ? 0 : handlers.size()));190 (handlers == null ? "0/0" : handlers.size()+"/"+handlerIds.size())); 183 191 return globalId; 184 192 } … … 196 204 if (handlers != null) 197 205 { 198 handlers.remove(localId); 206 synchronized (handlers) 207 { 208 handlers.remove(localId); 209 handlerIds.remove(handler); 210 } 199 211 // If called from the close() method() this is waiting for 200 212 if (notifyThread != null && handlers.size() == 0) … … 205 217 } 206 218 logger.debug("Current number of registered signal handlers: " + 207 (handlers == null ? 0 : handlers.size()));219 (handlers == null ? "0/0" : handlers.size()+"/"+handlerIds.size())); 208 220 } 209 221 … … 274 286 /** 275 287 Get the local signal handler id of the given signal handler. 276 This implementation simply return the system hashcode for the 277 handler. The returned ID must be unique among the registered 278 signal handlers. 288 This implementation generates a unique ID for the handler. 279 289 @param handler The handler to get the id for 280 290 @return The local handler id … … 282 292 protected String getLocalSignalHandlerId(SignalHandler handler) 283 293 { 284 return String.valueOf(System.identityHashCode(handler)); 294 if (handlerIds == null) return String.valueOf(System.identityHashCode(handler)); 295 String id = handlerIds.get(handler); 296 if (id == null) 297 { 298 synchronized (handlers) 299 { 300 while (true) 301 { 302 id = Application.generateRandomId(4); 303 if (!handlers.containsKey(id)) break; 304 } 305 handlerIds.put(handler, id); 306 } 307 } 308 return id; 285 309 } 286 310 -
trunk/src/core/net/sf/basedb/util/timer/ThreadTimerTask.java
r6127 r6684 85 85 public void run() 86 86 { 87 task.run(); 88 isExecuting = false; 87 try 88 { 89 task.run(); 90 } 91 finally 92 { 93 isExecuting = false; 94 } 89 95 } 90 96 } -
trunk/src/test/TestAnyToAny.java
r6100 r6684 71 71 test_exists(sampleId, "third", false); 72 72 73 // Test relinking to a new item in a single transaction 74 int sampleId2 = test_relink(id); 75 73 76 // Standard test: Delete 74 77 if (TestUtil.waitBeforeDelete()) TestUtil.waitForEnter(); … … 82 85 83 86 TestSample.test_delete(sampleId); 87 TestSample.test_delete(sampleId2); 84 88 TestFile.test_delete(fileId1); 85 89 TestFile.test_delete(fileId2); … … 121 125 } 122 126 127 static int test_relink(int id) 128 { 129 if (id == 0) return 0; 130 int sampleId = 0; 131 DbControl dc = null; 132 try 133 { 134 dc = TestUtil.getDbControl(); 135 Sample s = Sample.getNew(dc); 136 dc.saveItem(s); 137 138 AnyToAny a = AnyToAny.getById(dc, id); 139 a.setTo(s); 140 a.setDescription("Relinked "+new Date()); 141 dc.commit(); 142 143 sampleId = s.getId(); 144 dc = TestUtil.getDbControl(); 145 dc.reattachItem(a, false); 146 write_item(0, a); 147 if (a.getToId() != sampleId) 148 { 149 throw new BaseException("Relink failed: " + a.getToId() + " != " + sampleId); 150 } 151 write("--Relink any-to-any OK"); 152 } 153 catch (Throwable ex) 154 { 155 write("--Relink any-to-any FAILED"); 156 ex.printStackTrace(); 157 ok = false; 158 } 159 finally 160 { 161 if (dc != null) dc.close(); 162 } 163 return sampleId; 164 } 165 123 166 static void test_load(int id) 124 167 { … … 185 228 { 186 229 if (!TestUtil.getSilent()) System.out.println(i+":\t"+a.getId()+"\t"+a.getName()+"\t"+ 187 a.getDescription()+"\t"+a.getFrom ()+"\t"+a.getTo());230 a.getDescription()+"\t"+a.getFromType()+"["+a.getFromId()+"]\t"+a.getToType()+"["+a.getToId()+"]"); 188 231 } 189 232 static void write(String message) -
trunk/src/test/TestJarClassLoader.java
r6640 r6684 43 43 write("++Testing Jar class loader"); 44 44 45 test_load("JarPlugin.jar", "JarPlugin", false, true );45 test_load("JarPlugin.jar", "JarPlugin", false, true, false); 46 46 test_resource("JarPlugin.jar", "META-INF/MANIFEST.MF", false, true); 47 47 48 48 // Test parent delegation 49 test_load("JarPlugin.jar", "affymetrix.calvin.exception.CalvinException", false, true );49 test_load("JarPlugin.jar", "affymetrix.calvin.exception.CalvinException", false, true, false); 50 50 test_resource("JarPlugin.jar", "org/hibernate/hibernate-configuration-3.0.dtd", false, false); 51 test_load("JarPlugin.jar", "affymetrix.calvin.exception.CalvinException", true, false );51 test_load("JarPlugin.jar", "affymetrix.calvin.exception.CalvinException", true, false, true); 52 52 test_resource("JarPlugin.jar", "org/hibernate/hibernate-configuration-3.0.dtd", true, false); 53 53 … … 57 57 58 58 static void test_load(String jarPath, String className, 59 boolean delegateFirst, boolean expectLoadedByJarClassLoader )59 boolean delegateFirst, boolean expectLoadedByJarClassLoader, boolean useNewInstance) 60 60 { 61 61 try 62 62 { 63 JarClassLoader cl = (JarClassLoader)JarClassLoader.getInstance(jarPath); 63 JarClassLoader cl = useNewInstance ? 64 (JarClassLoader)JarClassLoader.newInstance(jarPath) : 65 (JarClassLoader)JarClassLoader.getInstance(jarPath); 64 66 cl.setDelegateFirst(delegateFirst); 65 67 Class c = cl.loadClass(className); -
trunk/www/WEB-INF/base.tld
r6655 r6684 62 62 <rtexprvalue>true</rtexprvalue> 63 63 </attribute> 64 <attribute> 65 <name>noskin</name> 66 <rtexprvalue>true</rtexprvalue> 67 </attribute> 64 68 </tag> 65 69 -
trunk/www/admin/annotationtypes/edit_annotationtype.jsp
r6608 r6684 861 861 data-initial-items="[<%=HTML.encodeTags(jsonUsableUnits.toJSONString()) %>]" 862 862 data-remove-to="allUnits" 863 size="10" multiple style="width: 100%;"863 size="10" multiple style="width: calc(100% - 10px);" 864 864 title="If no unit is selected, all units can be used" 865 865 > … … 886 886 </td> 887 887 <td style="width: 50%;"> 888 <select name="allUnits" id="allUnits" size="10" multiple style="width: 100%;">888 <select name="allUnits" id="allUnits" size="10" multiple style="width: calc(100% - 10px);"> 889 889 </select> 890 890 </td> -
trunk/www/admin/extensions/tree.jsp
r6409 r6684 49 49 <%@ taglib prefix="base" uri="/WEB-INF/base.tld" %> 50 50 <%! 51 JSONObject newJoustExtensionPoint( JSONObject jsonParent, ExtensionsControl ec, ExtensionPoint ep, ExtensionsFile ef)51 JSONObject newJoustExtensionPoint(DbControl dc, JSONObject jsonParent, ExtensionsControl ec, ExtensionPoint ep, ExtensionsFile ef) 52 52 { 53 53 String id = ep.getId(); … … 59 59 icon = "ExtensionPointError"; 60 60 } 61 JSONObject json = newJoustEntry( jsonParent, icon, HTML.encodeTags(name), id);61 JSONObject json = newJoustEntry(dc, jsonParent, icon, HTML.encodeTags(name), id); 62 62 json.put("type", "extension-point"); 63 63 return json; 64 64 } 65 65 66 JSONObject newJoustExtension( JSONObject jsonParent, ExtensionsControl ec, Extension ext, ExtensionsFile ef, boolean inGroup, boolean showFile)66 JSONObject newJoustExtension(DbControl dc, JSONObject jsonParent, ExtensionsControl ec, Extension ext, ExtensionsFile ef, boolean inGroup, boolean showFile) 67 67 { 68 68 String id = ext.getId(); … … 88 88 } 89 89 90 JSONObject json = newJoustEntry( jsonParent, icon, name, id);90 JSONObject json = newJoustEntry(dc, jsonParent, icon, name, id); 91 91 json.put("type", "extension"); 92 92 return json; 93 93 } 94 94 95 JSONObject newJoustFile( JSONObject jsonParent, ExtensionsFile ef, ExtensionsControl ec)95 JSONObject newJoustFile(DbControl dc, JSONObject jsonParent, ExtensionsFile ef, ExtensionsControl ec) 96 96 { 97 97 String efName = ef.getName(); … … 107 107 if (ef.checkModified()) icon += "Modified"; 108 108 109 JSONObject json = newJoustEntry( jsonParent, icon, HTML.encodeTags(efName), efName);109 JSONObject json = newJoustEntry(dc, jsonParent, icon, HTML.encodeTags(efName), efName); 110 110 json.put("id", efName); 111 111 json.put("type", "file"); … … 114 114 } 115 115 116 JSONObject newJoustExtensionGroup( JSONObject jsonParent, ExtensionsControl ec, Extension ext, String groupId)116 JSONObject newJoustExtensionGroup(DbControl dc, JSONObject jsonParent, ExtensionsControl ec, Extension ext, String groupId) 117 117 { 118 118 String id = ext.getId(); … … 120 120 String name = about == null || about.getName() == null ? id : about.getName(); 121 121 String icon = "Folder"; 122 JSONObject json = newJoustEntry( jsonParent, icon, HTML.encodeTags(name), groupId);122 JSONObject json = newJoustEntry(dc, jsonParent, icon, HTML.encodeTags(name), groupId); 123 123 json.put("type", "group"); 124 124 return json; 125 125 } 126 126 127 JSONObject newJoustPlugin( JSONObject jsonParent, ExtensionsControl ex, PluginInfo info, ExtensionsFile ef)127 JSONObject newJoustPlugin(DbControl dc, JSONObject jsonParent, ExtensionsControl ex, PluginInfo info, ExtensionsFile ef) 128 128 { 129 129 String id = info.getClassName(); … … 140 140 } 141 141 142 JSONObject json = newJoustEntry( jsonParent, icon, name, id);142 JSONObject json = newJoustEntry(dc, jsonParent, icon, name, id); 143 143 json.put("type", "plugin"); 144 144 json.put("className", info.getClassName()); … … 146 146 } 147 147 148 JSONObject newJoustEntry( JSONObject jsonParent, String icon, String text, String id)148 JSONObject newJoustEntry(DbControl dc, JSONObject jsonParent, String icon, String text, String id) 149 149 { 150 150 JSONObject jsonJoust = new JSONObject(); 151 151 jsonJoust.put("icon", icon); 152 152 jsonJoust.put("text", text); 153 jsonJoust.put("id", "joust-"+ System.identityHashCode(jsonJoust));153 jsonJoust.put("id", "joust-"+dc.uniqueRandom()); 154 154 jsonJoust.put("externalId", id); 155 155 if (jsonParent != null) … … 172 172 DbControl dc = null; 173 173 174 // Build the Joust menu tree 175 JSONArray jsonJoust = new JSONArray(); 176 177 // Two ROOT items: 178 JSONObject jsonByExtPoint = newJoustEntry(null, "Root", "By extension point", "root.by-extension-point");179 jsonByExtPoint.put("isOpen", 1); 180 JSONObject jsonByFile = newJoustEntry(null, "Root", "By file", "root.by-file"); 181 jsonByFile.put("isOpen", 1);182 183 // Group some extension points inside sub-folders 184 JSONObject jsonToolbars = newJoustEntry(jsonByExtPoint, "Folder", "Toolbars", "by-extension-point.toolbars");185 JSONObject jsonEditDialogs = newJoustEntry(jsonByExtPoint, "Folder", "Edit dialogs", "by-extension-point.edit-dialogs"); 186 JSONObject jsonListColumns = newJoustEntry(jsonByExtPoint, "Folder", "List columns", "by-extension-point.list-columns"); 187 188 jsonJoust.add(jsonByExtPoint);189 jsonJoust.add(jsonByFile);190 191 ExtensionsControl ec = ExtensionsControl.get(dc);192 List<ExtensionPoint<?>> extensionPoints = ec.getExtensionPoints();193 Collections.sort(extensionPoints, Registry.EXTENSIONPOINT_COMPARATOR); 194 for (ExtensionPoint ep : extensionPoints) 195 { 196 String id = ep.getId();197 JSONObject jsonParent = jsonByExtPoint;198 if (id.startsWith("net.sf.basedb.clients.web.toolbar.")) jsonParent = jsonToolbars;199 if (id.startsWith("net.sf.basedb.clients.web.tabcontrol.edit.")) jsonParent = jsonEditDialogs;200 if (id.startsWith("net.sf.basedb.clients.web.onsave.")) jsonParent = jsonEditDialogs;201 if (id.startsWith("net.sf.basedb.clients.web.listcolumn.")) jsonParent = jsonListColumns;202 203 JSONObject jsonEp = newJoustExtensionPoint(jsonParent, ec, ep, ec.getFileByObjectKey(new ExtensionPointKey(ep)));204 205 List<Extension<?>> extensions = ec.getExtensions(ep.getId());206 Collections.sort(extensions, Registry.EXTENSION_COMPARATOR);207 for (Extension ext : extensions)208 {209 newJoustExtension(jsonEp, ec, ext, ec.getFileByObjectKey(new ExtensionKey(ext)), false, true);210 }211 } 212 213 for (ExtensionsFile ef : ec.getFiles()) 214 { 215 if (!ef.isInstalled()) continue;216 217 JSONObject jsonFile = newJoustFile(jsonByFile, ef, ec);218 219 List<ExtensionPoint> eps = ef.getObjectsOfClass(ExtensionPoint.class);220 Collections.sort(eps, Registry.EXTENSIONPOINT_COMPARATOR);221 for (ExtensionPoint ep : eps)222 {223 newJoustExtensionPoint(jsonFile, ec, ep, ef);224 }225 226 List<Extension> exts = ef.getObjectsOfClass(Extension.class);227 Collections.sort(exts, Registry.EXTENSION_COMPARATOR);228 String currentGroupId = null;229 JSONObject jsonGroup = null;230 231 for (Extension ext : exts)232 {233 int groupIndex = ext.getId().indexOf(":");234 // ID:s containing ':' should be grouped235 if (groupIndex > 0)236 {237 String groupId = ext.getId().substring(0, groupIndex);238 if ( !groupId.equals(currentGroupId))174 try 175 { 176 dc = sc.newDbControl(); 177 // Build the Joust menu tree 178 JSONArray jsonJoust = new JSONArray(); 179 180 // Two ROOT items: 181 JSONObject jsonByExtPoint = newJoustEntry(dc, null, "Root", "By extension point", "root.by-extension-point"); 182 jsonByExtPoint.put("isOpen", 1); 183 JSONObject jsonByFile = newJoustEntry(dc, null, "Root", "By file", "root.by-file"); 184 jsonByFile.put("isOpen", 1); 185 186 // Group some extension points inside sub-folders 187 JSONObject jsonToolbars = newJoustEntry(dc, jsonByExtPoint, "Folder", "Toolbars", "by-extension-point.toolbars"); 188 JSONObject jsonEditDialogs = newJoustEntry(dc, jsonByExtPoint, "Folder", "Edit dialogs", "by-extension-point.edit-dialogs"); 189 JSONObject jsonListColumns = newJoustEntry(dc, jsonByExtPoint, "Folder", "List columns", "by-extension-point.list-columns"); 190 191 jsonJoust.add(jsonByExtPoint); 192 jsonJoust.add(jsonByFile); 193 194 ExtensionsControl ec = ExtensionsControl.get(dc); 195 List<ExtensionPoint<?>> extensionPoints = ec.getExtensionPoints(); 196 Collections.sort(extensionPoints, Registry.EXTENSIONPOINT_COMPARATOR); 197 for (ExtensionPoint ep : extensionPoints) 198 { 199 String id = ep.getId(); 200 JSONObject jsonParent = jsonByExtPoint; 201 if (id.startsWith("net.sf.basedb.clients.web.toolbar.")) jsonParent = jsonToolbars; 202 if (id.startsWith("net.sf.basedb.clients.web.tabcontrol.edit.")) jsonParent = jsonEditDialogs; 203 if (id.startsWith("net.sf.basedb.clients.web.onsave.")) jsonParent = jsonEditDialogs; 204 if (id.startsWith("net.sf.basedb.clients.web.listcolumn.")) jsonParent = jsonListColumns; 205 206 JSONObject jsonEp = newJoustExtensionPoint(dc, jsonParent, ec, ep, ec.getFileByObjectKey(new ExtensionPointKey(ep))); 207 208 List<Extension<?>> extensions = ec.getExtensions(ep.getId()); 209 Collections.sort(extensions, Registry.EXTENSION_COMPARATOR); 210 for (Extension ext : extensions) 211 { 212 newJoustExtension(dc, jsonEp, ec, ext, ec.getFileByObjectKey(new ExtensionKey(ext)), false, true); 213 } 214 } 215 216 for (ExtensionsFile ef : ec.getFiles()) 217 { 218 if (!ef.isInstalled()) continue; 219 220 JSONObject jsonFile = newJoustFile(dc, jsonByFile, ef, ec); 221 222 List<ExtensionPoint> eps = ef.getObjectsOfClass(ExtensionPoint.class); 223 Collections.sort(eps, Registry.EXTENSIONPOINT_COMPARATOR); 224 for (ExtensionPoint ep : eps) 225 { 226 newJoustExtensionPoint(dc, jsonFile, ec, ep, ef); 227 } 228 229 List<Extension> exts = ef.getObjectsOfClass(Extension.class); 230 Collections.sort(exts, Registry.EXTENSION_COMPARATOR); 231 String currentGroupId = null; 232 JSONObject jsonGroup = null; 233 234 for (Extension ext : exts) 235 { 236 int groupIndex = ext.getId().indexOf(":"); 237 // ID:s containing ':' should be grouped 238 if (groupIndex > 0) 239 239 { 240 currentGroupId = groupId; 241 jsonGroup = newJoustExtensionGroup(jsonFile, ec, ext, currentGroupId); 240 String groupId = ext.getId().substring(0, groupIndex); 241 if (!groupId.equals(currentGroupId)) 242 { 243 currentGroupId = groupId; 244 jsonGroup = newJoustExtensionGroup(dc, jsonFile, ec, ext, currentGroupId); 245 } 242 246 } 243 } 244 else 245 { 246 currentGroupId = null; 247 jsonGroup = null; 248 } 249 newJoustExtension(jsonGroup != null ? jsonGroup : jsonFile, ec, ext, ef, jsonGroup != null, false); 250 } 251 List<PluginInfo> plugins = ef.getObjectsOfClass(PluginInfo.class); 252 Collections.sort(plugins, PluginInfo.NAME_COMPARATOR); 253 for (PluginInfo info : plugins) 254 { 255 newJoustPlugin(jsonFile, ec, info, ef); 256 } 257 } 258 259 260 try 261 { 262 dc = sc.newDbControl(); 247 else 248 { 249 currentGroupId = null; 250 jsonGroup = null; 251 } 252 newJoustExtension(dc, jsonGroup != null ? jsonGroup : jsonFile, ec, ext, ef, jsonGroup != null, false); 253 } 254 List<PluginInfo> plugins = ef.getObjectsOfClass(PluginInfo.class); 255 Collections.sort(plugins, PluginInfo.NAME_COMPARATOR); 256 for (PluginInfo info : plugins) 257 { 258 newJoustPlugin(dc, jsonFile, ec, info, ef); 259 } 260 } 263 261 %> 264 262 <base:page title="" type="iframe"> -
trunk/www/admin/roles/edit_role.jsp
r6291 r6684 199 199 ><label for="act_as_another_user">Act as another user</label><br> 200 200 <input type="checkbox" name="select_jobagent" id="select_jobagent" 201 <%=PermissionUtil.getPermissionCode(EnumSet.of(Permission.SELECT_JOBAGENT))%>201 value="<%=PermissionUtil.getPermissionCode(EnumSet.of(Permission.SELECT_JOBAGENT))%>" 202 202 <%=hasSelectJobagent ? "checked" : ""%> 203 203 ><label for="select_jobagent">Select job agent for jobs</label><br> -
trunk/www/common/annotations/inherit.js
r6389 r6684 48 48 inherit.onSelect = function(event) 49 49 { 50 var frm = document.forms['annotations']; 50 51 var menuItem = event.target.item; 51 52 if (menuItem.type == 'annotation') … … 53 54 Doc.element('annotationType').innerHTML = menuItem.annotationType; 54 55 Doc.element('annotationValues').innerHTML = menuItem.values; 56 menuItem.modified = menuItem.inherited != frm[menuItem.id].checked; 55 57 } 56 58 else if (menuItem.type == 'annotation-set') … … 58 60 if (menuItem.children) 59 61 { 60 var frm = document.forms['annotations'];61 62 var checked = frm[menuItem.id].checked; 62 63 // If the annotation-set is checked all child items should … … 67 68 { 68 69 var child = menuItem.children[childNo]; 69 frm[child.id].checked = checked || child.inherited;70 frm[child.id].checked = checked || (child.inherited != child.modified); 70 71 frm[child.id].disabled = checked; 71 72 } … … 73 74 } 74 75 75 inherit.saveInheritedAnnotationsToForm();76 76 } 77 77 … … 86 86 87 87 var aFrm = document.forms['annotations']; 88 var menuElements = tree.getElementsByClassName(' menuitem');88 var menuElements = tree.getElementsByClassName('joustitem'); 89 89 for (var menuNo = 0; menuNo < menuElements.length; menuNo++) 90 90 { … … 120 120 } 121 121 } 122 123 122 if (frm.addedAnnotations) 124 123 { -
trunk/www/common/columns/configure.js
r6389 r6684 122 122 { 123 123 var option = new Option(column.title, column.id); 124 option.title = column.title; 124 125 if (column.alwaysShow) 125 126 { -
trunk/www/common/overview/failures.js
r6400 r6684 43 43 else 44 44 { 45 var failureId = Data.get(target, 'failure-id');46 45 var nodeId = Data.get(target, 'node-id'); 47 46 window.parent.frames['tree'].Tree.selectNode(nodeId); -
trunk/www/common/overview/failures.jsp
r6621 r6684 157 157 { 158 158 index++; 159 String failureId = "F" + System.identityHashCode(failure);160 159 Node node = failure.getNode(); 161 160 BasicItem item = node.getItem(); 162 161 %> 163 <tr id="<%=failureId%>"class="failure highlight auto-init" data-auto-init="failure"164 data- failure-id="<%=failureId%>" data-node-id="<%=node.getId()%>"162 <tr class="failure highlight auto-init" data-auto-init="failure" 163 data-node-id="<%=node.getId()%>" 165 164 <% 166 165 if (item != null) -
trunk/www/common/overview/options.jsp
r6608 r6684 82 82 width: 17em; 83 83 max-width: 17em; 84 } 85 86 .special select 87 { 88 min-width: 14em; 84 89 } 85 90 -
trunk/www/common/plugin/parse_file.jsp
r6621 r6684 446 446 </div> 447 447 448 <div class="absolutefull topborder" style="top: 2em;"> 449 450 <table class="fullform input100 special larger"> 451 <tbody class="sectionheader"> 452 <tr> 453 <th class="rightborder">Property</th> 454 <th class="rightborder">Mapping expression</th> 455 <th>File columns</th> 456 </tr> 457 </tbody> 458 <% 459 for (String name : mappingParameters) 460 { 461 %> 462 <tr class="highlight"> 463 <th><%=HTML.encodeTags(request.getParameter("mapping." + name + ".label"))%></th> 464 <td> 465 <table style="width: 100%;"> 466 <tr> 467 <td> 468 <input type="text" class="text auto-init" data-auto-init="column-mapping" 469 name="mapping.<%=name%>.expression" 470 maxlength="80" 471 value="<%=HTML.encodeTags(request.getParameter("mapping." + name + ".expression"))%>"> 472 </td> 473 <td style="width: 22px;"> 474 <base:icon image="cancel.png" subclass="auto-init" id="<%="clear."+name %>" 475 data-auto-init="column-mapping-clear" data-mapping="<%=name%>" 476 tooltip="Clear this expression"/> 477 </td> 478 </tr> 479 </table> 480 </td> 481 <td style="width: 15em;"> 482 <select name="list.<%=name%>" class="auto-init" 483 data-auto-init="column-mapping-preset" data-mapping="<%=name%>"> 484 <option value=""> 485 <%=mappings%> 486 </select> 487 </td> 488 </tr> 489 <% 490 } 491 %> 492 <tr class="dynamic"> 493 <th></th> 494 <td></td> 495 <td></td> 496 </tr> 497 </table> 448 <div class="absolutefull input100" style="top: 2em;"> 449 450 <tbl:table id="col-mappings"> 451 <tbl:columndef 452 id="property" 453 title="Property" 454 /> 455 <tbl:columndef 456 id="expression" 457 title="Mapping expression" 458 /> 459 <tbl:columndef 460 id="columns" 461 title="File columns" 462 /> 463 <tbl:data> 464 <tbl:headers> 465 <tbl:headerrow> 466 <tbl:columnheaders /> 467 </tbl:headerrow> 468 </tbl:headers> 469 <tbl:rows> 470 <% 471 for (String name : mappingParameters) 472 { 473 %> 474 <tbl:row> 475 <tbl:cell column="property"><%=HTML.encodeTags(request.getParameter("mapping." + name + ".label"))%></tbl:cell> 476 <tbl:cell column="expression"> 477 478 <table style="width: 100%;"> 479 <tr> 480 <td> 481 <input type="text" class="text auto-init" data-auto-init="column-mapping" 482 name="mapping.<%=name%>.expression" 483 maxlength="80" 484 value="<%=HTML.encodeTags(request.getParameter("mapping." + name + ".expression"))%>"> 485 </td> 486 <td style="width: 22px;"> 487 <base:icon image="cancel.png" subclass="auto-init" id="<%="clear."+name %>" 488 data-auto-init="column-mapping-clear" data-mapping="<%=name%>" 489 tooltip="Clear this expression"/> 490 </td> 491 </tr> 492 </table> 493 </tbl:cell> 494 495 <tbl:cell column="columns"> 496 <select name="list.<%=name%>" class="auto-init" 497 data-auto-init="column-mapping-preset" data-mapping="<%=name%>"> 498 <option value=""> 499 <%=mappings%> 500 </select> 501 </tbl:cell> 502 503 </tbl:row> 504 <% 505 } 506 %> 507 </tbl:rows> 508 </tbl:data> 509 </tbl:table> 498 510 </div> 499 511 </form> -
trunk/www/filemanager/select_file.jsp
r6540 r6684 42 42 43 43 <base:body> 44 <h1 ><%=requestTitle == null ? title : requestTitle%></h1>44 <h1 style="border-bottom-width: 0;"><%=requestTitle == null ? title : requestTitle%></h1> 45 45 <div class="content bottomborder"> 46 46 <div id="page-data" class="datacontainer" -
trunk/www/include/scripts/main-2.js
r6621 r6684 2410 2410 { 2411 2411 list = Doc.element(list); 2412 if ( list.style.width)2413 { 2414 forms.checkOptionText(list.style.width, option);2412 if (option.hasAttribute('text') && !option.hasAttribute('title')) 2413 { 2414 option.title = option.text; 2415 2415 } 2416 2416 if (index < 0 || index >= list.length) … … 2425 2425 } 2426 2426 2427 /**2428 Check the length text attribute of a selection list option against2429 the width of the selection list. If the text is longer than what2430 can be displayed in the list, the text is automatically shortened2431 and ... is appended. The full text is made available as a popup2432 tooltip. If the text ends with a part inside brackets, [],2433 that part is preserved, chopping is done on the text preceeding it.2434 @param listWidth Width og the list including unit (em or px is supported)2435 @param option The option that is beeing added to the list2436 */2437 forms.checkOptionText = function(listWidth, option)2438 {2439 var width = listWidth.match(/(\d+)(em|px)/);2440 if (width == null) return;2441 var maxLength;2442 if (width[2] == 'em')2443 {2444 maxLength = 1.2 * width[1] + 0.01 * width[1] * width[1];2445 }2446 else2447 {2448 maxLength = 0.1 * width[1];2449 }2450 var hellip = String.fromCharCode(8230);2451 if (option.text && option.text.length > maxLength)2452 {2453 var text = option.text;2454 option.title = text;2455 var parts = text.match(/(.*)\[(.*)\]/);2456 if (parts != null)2457 {2458 maxLength = maxLength - parts[2].length - 3;2459 if (maxLength < 4) maxLength = 4;2460 text = parts[1].substring(0, maxLength) + hellip + ' [' + parts[2] + ']';2461 }2462 else2463 {2464 text = text.substring(0, maxLength) + hellip;2465 }2466 option.text = text;2467 }2468 }2469 2470 2427 /** 2471 2428 Switch place of two options in a list -
trunk/www/info/about.jsp
r6610 r6684 38 38 import="java.sql.Driver" 39 39 import="java.util.Properties" 40 import="java.util.List" 41 import="java.lang.management.ManagementFactory" 42 import="java.lang.management.MemoryPoolMXBean" 43 import="java.lang.management.MemoryType" 44 import="java.lang.management.MemoryUsage" 40 45 %> 41 46 <%@ taglib prefix="base" uri="/WEB-INF/base.tld" %> … … 63 68 final Properties properties = System.getProperties(); 64 69 final Runtime runtime = Runtime.getRuntime(); 65 70 List<MemoryPoolMXBean> beans = ManagementFactory.getMemoryPoolMXBeans(); 66 71 %> 67 72 <base:page type="popup" title="About"> 68 <base:head scripts="tabcontrol-2.js,~info.js" styles="tabcontrol.css" /> 73 <base:head scripts="tabcontrol-2.js,~info.js" styles="tabcontrol.css"> 74 <style> 75 #memoryTable th, #memoryTable td 76 { 77 text-align: right; 78 padding-left: 1em; 79 padding-right: 1.5em; 80 } 81 82 .memory-warning 83 { 84 color: #C80000; 85 font-weight: bold; 86 background-image: url('../images/warning_small.png'); 87 background-repeat: no-repeat; 88 background-position: 100% 50%; 89 } 90 </style> 91 </base:head> 69 92 <base:body data-read-only="1"> 70 93 <h1>BASE - BioArray Software Environment</h1> … … 135 158 </td> 136 159 </tr> 137 <tr >160 <tr class="dynamic"> 138 161 <th>Memory</th> 139 <td class="info">Total: <%=Values.formatBytes(runtime.totalMemory())%><br> 140 Free: <%=Values.formatBytes(runtime.freeMemory()) %><br> 141 Max: <%=Values.formatBytes(runtime.maxMemory()) %></td> 142 </tr> 143 <tr class="dynamic"> 144 <th></th> 145 <td></td> 162 <td class="info"> 163 164 <table id="memoryTable" style="xwidth:100%;"> 165 <tr style="border-bottom-width: 1px;"> 166 <th></th> 167 <th>Used</th> 168 <th>Max</th> 169 <th></th> 170 </tr> 171 <% 172 for (MemoryType mtype : MemoryType.values()) 173 { 174 long sumUsed = 0; 175 long sumMax = 0; 176 for (MemoryPoolMXBean mbean : beans) 177 { 178 if (mbean.getType() == mtype) 179 { 180 MemoryUsage usage = mbean.getUsage(); 181 sumUsed += usage.getUsed(); 182 sumMax += usage.getMax(); 183 long percent = 100*usage.getUsed() / usage.getMax(); 184 %> 185 <tr> 186 <td><%=mbean.getName() %></td> 187 <td><%=Values.formatBytes(usage.getUsed()) %></td> 188 <td><%=Values.formatBytes(usage.getMax()) %></td> 189 <td class="<%=percent > 75 ? "memory-warning" : "" %>"><%=percent %>%</td> 190 </tr> 191 <% 192 } 193 } 194 %> 195 <tr style="border-bottom-width: 1px; font-weight: bold;"> 196 <td>Sum <%=mtype.toString() %></td> 197 <td><%=Values.formatBytes(sumUsed) %></td> 198 <td><%=Values.formatBytes(sumMax) %></td> 199 <td><%=100*sumUsed / sumMax %>%</td> 200 </tr> 201 <% 202 } 203 %> 204 205 </table> 146 206 </tr> 147 207 </table> -
trunk/www/lims/arrayslides/create_wizard.jsp
r6312 r6684 192 192 <tbody class="sectionheader"> 193 193 <tr> 194 <th > </th>195 <th >Name:194 <th style="border-top-width: 0;"> </th> 195 <th style="border-top-width: 0;">Name: 196 196 <base:icon 197 197 id="pasteMultipleName" … … 207 207 /> 208 208 </th> 209 <th >Barcode:209 <th style="border-top-width: 0;">Barcode: 210 210 <base:icon 211 211 id="pasteMultipleBarcode" -
trunk/www/views/experiments/index.jsp
r6315 r6684 453 453 cloneJob.setParameterValue("cloneSource", "Clone source", null, 454 454 new StringParameterType(), request.getParameter("cloneSource")); 455 cloneJob.setScheduled(null, null); 455 456 dc.saveItem(cloneJob); 456 457 dc.commit(); -
trunk/www/views/jobs/view_job.jsp
r6621 r6684 303 303 %> 304 304 <td style="padding-left: 10px;"><base:button 305 subclass=" linkauto-init"305 subclass="auto-init" 306 306 data-auto-init="view-file" 307 307 data-file-id="<%=logFile.getId()%>" -
trunk/www/views/physicalbioassays/list_bioassays.jsp
r6604 r6684 235 235 id="derivedBioAssays" 236 236 title="Derived bioassays" 237 property="&rootDerivedBioAssays( name)"237 property="&rootDerivedBioAssays(%name)" 238 238 datatype="string" 239 239 filterable="true"
Note: See TracChangeset
for help on using the changeset viewer.