Changeset 5686
- Timestamp:
- Aug 5, 2011, 2:54:06 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/core/net/sf/basedb/core/ItemContext.java
r5590 r5686 727 727 728 728 /** 729 Add an item to the "recently used items" list when used for a specific 730 item subtype. Each type of item+subtype has their own list which may contain at 731 most <code>maxInList</code> items. 732 <p> 733 Note! The lists are stored as string of colon-separated ID:s in 734 the setting given by the item type. For example the recently used 735 protocols are found in the setting: 736 <code>getSetting("PROTOCOL.#subtype-id.recent")</code>. Client code is advised to 737 not change these settings. 738 739 @param item The item to add 740 @param subtype The subtype of the parent item (can be null) 741 @param maxInList The maximum number of items in the list 742 @since 3.0 743 */ 744 public void setRecent(BasicItem item, ItemSubtype subtype, int maxInList) 745 { 746 if (subtype == null) 747 { 748 setRecent(item, maxInList); 749 } 750 else 751 { 752 setRecent(item, "#"+subtype.getId(), maxInList); 753 } 754 } 755 756 /** 729 757 Add an item to the "recently used items" list. Each type of item 730 758 has their own list and sublists which may contain at … … 783 811 784 812 /** 813 Get the number of recently used items in the list. 814 @param itemType The type of items 815 @param subtype The subtype of the parent item (can be null) 816 @since 3.0 817 */ 818 public int getNumRecent(Item itemType, ItemSubtype subtype) 819 { 820 if (subtype == null) 821 { 822 return getNumRecent(itemType); 823 } 824 else 825 { 826 return getNumRecent(itemType, "#"+subtype.getId()); 827 } 828 } 829 830 /** 785 831 Get the number of recently used items in a list with a sublist. 786 832 @param itemType The type of items … … 816 862 { 817 863 return loadRecent(dc, itemType, itemType.name()); 864 } 865 866 /** 867 Get all recently used items of the specified type. The list 868 only contains items that the logged in user has read permission 869 to and that hasn't been deleted. Thus, the {@link #getNumRecent(Item, ItemSubtype)} 870 may return a larger number than what is actually returned in this 871 list. 872 873 @param dc The DbControl used to access the database 874 @param itemType The type of items 875 @param subtype The subtype of the parent item (can be null) 876 @return A list with the items 877 @since 3.0 878 */ 879 public List<? extends BasicItem> getRecent(DbControl dc, Item itemType, ItemSubtype subtype) 880 { 881 if (subtype == null) 882 { 883 return getRecent(dc, itemType); 884 } 885 else 886 { 887 return getRecent(dc, itemType, "#" + subtype.getId()); 888 } 818 889 } 819 890 … … 923 994 setRecent(itemType.name(), null); 924 995 } 925 996 997 /** 998 Clear the recently used items list from items of the specified type. 999 @param itemType The type of items 1000 @param subtype The subtype of the parent item (can be null) 1001 @since 3.0 1002 */ 1003 public void clearRecent(Item itemType, ItemSubtype subtype) 1004 { 1005 if (subtype == null) 1006 { 1007 clearRecent(itemType); 1008 } 1009 else 1010 { 1011 clearRecent(itemType, "#" + subtype.getId()); 1012 } 1013 } 1014 1015 926 1016 /** 927 1017 Clear the recently used items sublist from items of the specified type. -
trunk/src/core/net/sf/basedb/core/ItemSubtype.java
r5651 r5686 35 35 import net.sf.basedb.core.query.Expressions; 36 36 import net.sf.basedb.core.query.Hql; 37 import net.sf.basedb.core.query.Orders; 37 38 import net.sf.basedb.core.query.Restrictions; 38 39 import net.sf.basedb.util.ClassUtil; … … 121 122 /** 122 123 Utility method for loading a subtype that is related to the subtype of the given item. 124 This is more or less equivalent to calling {@link Subtypable#getItemSubtype()} and 125 then {@link ItemSubtype#getRelatedSubtype(Item)} but with proper null handling and 126 a possibility to return a default subtype if no related one can be found. 127 123 128 @param dc A DbControl to use for database access 124 129 @param item A subtypable item … … 172 177 173 178 return null; 179 } 180 181 /** 182 Utility method for locating all subtypes that have a relationship to the 183 subtype of the given item. This is more or less equivalent to finding 184 all subtypes were the method {@link ItemSubtype#getRelatedSubtype(Item)} 185 return the subtype of the given subtypable item (optionally restricting 186 to one parent item type). 187 188 @param dc A DbControl to use for database access 189 @param item A subtypeable item 190 @param parentType The item type of the subtypes that we want to find or null 191 to find any subtype 192 @return A list with the subtypes, or an empty list if none could be found 193 */ 194 public static List<ItemSubtype> getParentSubtypes(DbControl dc, Subtypable item, Item parentType) 195 { 196 ItemSubtype subtype = item.getItemSubtype(); 197 if (subtype == null) return Collections.emptyList(); 198 199 ItemQuery<ItemSubtype> query = subtype.getParentSubtypes(); 200 if (parentType != null) 201 { 202 query.restrict(Restrictions.eq(Hql.property("itemType"), Expressions.integer(parentType.getValue()))); 203 } 204 query.order(Orders.asc(Hql.property("name"))); 205 return query.list(dc); 174 206 } 175 207 -
trunk/www/admin/itemsubtypes/ajax.jsp
r5650 r5686 26 26 import="net.sf.basedb.core.DbControl" 27 27 import="net.sf.basedb.core.Item" 28 import="net.sf.basedb.core.ItemContext" 28 29 import="net.sf.basedb.core.ItemSubtype" 29 30 import="net.sf.basedb.core.Subtypable" 31 import="net.sf.basedb.core.BasicItem" 32 import="net.sf.basedb.core.Nameable" 30 33 import="net.sf.basedb.core.InvalidDataException" 31 34 import="net.sf.basedb.util.Values" … … 34 37 import="net.sf.basedb.clients.web.WebException" 35 38 import="org.json.simple.JSONObject" 39 import="org.json.simple.JSONArray" 40 import="java.util.List" 36 41 %> 37 42 <% … … 82 87 dc.close(); 83 88 } 89 else if ("GetRecentAndRelated".equals(cmd)) 90 { 91 dc = sc.newDbControl(); 92 93 ItemSubtype subtype = itemId == 0 ? null : ItemSubtype.getById(dc, itemId); 94 Item mainItemType = subtype == null ? Item.valueOf(request.getParameter("itemType")) : subtype.getMainItemType(); 95 ItemContext cc = sc.getCurrentContext(mainItemType); 96 97 if (subtype != null) 98 { 99 json.put("id", subtype.getId()); 100 json.put("name", subtype.getName()); 101 } 102 103 for (String relatedType : request.getParameterValues("relatedType")) 104 { 105 JSONObject jsonITEM = new JSONObject(); 106 Item relatedItem = Item.valueOf(relatedType); 107 108 // Load the related subtype 109 if (subtype != null) 110 { 111 ItemSubtype relatedSubtype = subtype.getRelatedSubtype(relatedItem); 112 if (relatedSubtype != null) 113 { 114 JSONObject jsonRelated = new JSONObject(); 115 jsonRelated.put("id", relatedSubtype.getId()); 116 jsonRelated.put("name", relatedSubtype.getName()); 117 jsonITEM.put("related", jsonRelated); 118 } 119 } 120 121 // Load the most recently used items 122 List<? extends BasicItem> recentItems = cc.getRecent(dc, relatedItem, subtype); 123 if (recentItems != null && recentItems.size() > 0) 124 { 125 JSONArray jsonRecent = new JSONArray(); 126 for (BasicItem recent : recentItems) 127 { 128 JSONObject jsonRecentItem = new JSONObject(); 129 jsonRecentItem.put("id", recent.getId()); 130 jsonRecentItem.put("name", ((Nameable)recent).getName()); 131 jsonRecent.add(jsonRecentItem); 132 } 133 jsonITEM.put("recent", jsonRecent); 134 } 135 json.put(relatedType, jsonITEM); 136 } 137 dc.close(); 138 } 84 139 else 85 140 { -
trunk/www/admin/itemsubtypes/list_subtypes.jsp
r5645 r5686 92 92 Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc); 93 93 94 ItemQuery<ItemSubtype> relatedQuery = ItemSubtype.getQuery(null); 95 relatedQuery.join(Hql.innerJoin("parents", "pp")); 96 relatedQuery.restrict(Restrictions.eq(Hql.alias("pp"), Hql.entityParameter("subtype", Item.ITEMSUBTYPE))); 97 relatedQuery.order(Orders.asc(Hql.property("name"))); 98 relatedQuery.include(cc.getInclude()); 99 94 100 Map<Plugin.MainType, Integer> pluginCount = PluginDefinition.countPlugins(dc, guiContext); 95 101 try … … 258 264 exportable="true" 259 265 /> 266 <tbl:columndef 267 id="relatedTypes" 268 property="&relatedSubtypes(name)" 269 datatype="string" 270 title="Related item types" 271 filterable="true" 272 exportable="true" 273 /> 260 274 <tbl:columndef 261 275 id="description" … … 423 437 <tbl:cell column="systemId"><%=Values.getString(item.getSystemId())%></tbl:cell> 424 438 <tbl:cell column="itemType"><%=item.getMainItemType()%></tbl:cell> 439 <tbl:cell column="relatedTypes"> 440 <% 441 relatedQuery.setEntityParameter("subtype", item); 442 String separator = ""; 443 for (ItemSubtype related : relatedQuery.list(dc)) 444 { 445 out.write(separator); 446 if (mode.hasPropertyLink()) 447 { 448 out.write(Base.getLinkedName(ID, related, false, mode.hasEditLink())); 449 } 450 else 451 { 452 out.write(HTML.encodeTags(related.getName())); 453 } 454 out.write(" (" + related.getMainItemType() + ")"); 455 separator = ", "; 456 } 457 %> 458 </tbl:cell> 425 459 <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell> 426 460 </tbl:row> -
trunk/www/biomaterials/samples/edit_sample.jsp
r5664 r5686 53 53 import="net.sf.basedb.clients.web.util.HTML" 54 54 import="net.sf.basedb.util.Values" 55 import="net.sf.basedb.util.ListUtil" 55 56 import="net.sf.basedb.util.formatter.WellCoordinateFormatter" 56 57 import="net.sf.basedb.util.formatter.Formatter" … … 66 67 import="java.util.HashSet" 67 68 import="java.util.Date" 69 import="java.util.Collections" 68 70 %> 69 71 <%@ taglib prefix="base" uri="/WEB-INF/base.tld" %> … … 89 91 90 92 boolean readCurrentSubtype = true; 91 int currentSubtypeId = 0;93 ItemSubtype currentSubtype = null; 92 94 boolean readCurrentProtocol = true; 93 95 Protocol currentProtocol = null; … … 102 104 BioPlate currentBioPlate = null; 103 105 104 // Load recently used items105 List<Protocol> recentProtocols = (List<Protocol>)cc.getRecent(dc, Item.PROTOCOL);106 List<BioSource> recentBioSources = (List<BioSource>)cc.getRecent(dc, Item.BIOSOURCE);107 List<BioPlate> recentBioPlates = (List<BioPlate>)cc.getRecent(dc, Item.BIOPLATE);108 109 106 WellCoordinateFormatter rowFormatter = new WellCoordinateFormatter(true); 110 107 WellCoordinateFormatter columnFormatter = new WellCoordinateFormatter(false); … … 124 121 } 125 122 } 126 127 123 128 124 if (itemId == 0) … … 130 126 title = "Create sample"; 131 127 cc.removeObject("item"); 132 currentSubtypeId = Values.getInt(request.getParameter("subtype_id"));133 if (currentSubtypeId == 0)134 {135 int recentSubtypeId = Values.getInt(cc.getRecent(Item.ITEMSUBTYPE.name(), 0));136 currentSubtypeId = Values.getInt(cc.getPropertyValue("itemSubtype"), recentSubtypeId);137 }138 128 if (cc.getPropertyFilter("creationEvent.protocol.name") != null) 139 129 { … … 142 132 int bioSourceId = Values.getInt(request.getParameter("biosource_id")); 143 133 int sampleId = Values.getInt(request.getParameter("sample_id")); 134 int currentSubtypeId = Values.getInt(request.getParameter("subtype_id")); 135 List<ItemSubtype> relatedToParent = Collections.emptyList(); 144 136 if (bioSourceId != 0) 145 137 { … … 147 139 parentType = Item.BIOSOURCE; 148 140 name = currentBioSource.getName() + ".s" + (currentBioSource.countSamples() + 1); 141 if (currentSubtypeId == 0) 142 { 143 relatedToParent = ItemSubtype.getParentSubtypes(dc, currentBioSource, Item.SAMPLE); 144 } 149 145 } 150 146 else if (sampleId != 0) … … 155 151 samplesQuery = Sample.getQuery(); 156 152 samplesQuery.restrict(Restrictions.eq(Hql.property("id"), Expressions.integer(sampleId))); 153 if (currentSubtypeId == 0) 154 { 155 relatedToParent = ItemSubtype.getParentSubtypes(dc, s, Item.SAMPLE); 156 } 157 157 } 158 158 else if (Values.getBoolean(request.getParameter("pooled"))) … … 167 167 { 168 168 name = Values.getString(cc.getPropertyValue("name"), "New sample"); 169 } 170 if (currentSubtypeId == 0) 171 { 172 if (relatedToParent.size() > 0) 173 { 174 // Find most recently used related subtype 175 List<ItemSubtype> recentSubtypes = (List<ItemSubtype>)cc.getRecent(dc, Item.ITEMSUBTYPE); 176 currentSubtype = ListUtil.findFirstCommon(recentSubtypes, relatedToParent, relatedToParent.get(0)); 177 } 178 else 179 { 180 int recentSubtypeId = Values.getInt(cc.getRecent(Item.ITEMSUBTYPE.name(), 0)); 181 currentSubtypeId = Values.getInt(cc.getPropertyValue("itemSubtype"), recentSubtypeId); 182 if (currentSubtypeId > 0) currentSubtype = ItemSubtype.getById(dc, currentSubtypeId); 183 } 169 184 } 170 185 eventDate = (Date)cc.getPropertyObject("creationEvent.eventDate"); … … 185 200 try 186 201 { 187 ItemSubtype subtype = sample.getItemSubtype(); 188 if (subtype != null) currentSubtypeId = subtype.getId(); 202 currentSubtype = sample.getItemSubtype(); 189 203 } 190 204 catch (PermissionDeniedException ex) … … 235 249 } 236 250 } 251 252 // Load recently used items 253 List<Protocol> recentProtocols = (List<Protocol>)cc.getRecent(dc, Item.PROTOCOL, currentSubtype); 254 List<BioSource> recentBioSources = (List<BioSource>)cc.getRecent(dc, Item.BIOSOURCE); 255 List<BioPlate> recentBioPlates = (List<BioPlate>)cc.getRecent(dc, Item.BIOPLATE); 237 256 238 257 // Query to retrieve item types … … 347 366 } 348 367 368 function subtypeOnChange() 369 { 370 var frm = document.forms['sample']; 371 var subtypeId = ItemSubtype.getSubtypeId('sample'); 372 var recentInfo = ItemSubtype.getRecentAndRelatedInfo(subtypeId, 'SAMPLE', ['PROTOCOL', 'BIOSOURCE', 'SAMPLE']); 373 protocolChanged = ItemSubtype.updateRecentItemsInList(frm.protocol_id, recentInfo.PROTOCOL.recent); 374 } 375 349 376 function selectProtocolOnClick() 350 377 { … … 633 660 <td colspan="2"> 634 661 <select name="subtype_id" 635 <%=!readCurrentSubtype ? "disabled readonly class=\"disabled selectionlist\"" : "class=\"selectionlist\""%>> 662 <%=!readCurrentSubtype ? "disabled readonly class=\"disabled selectionlist\"" : "class=\"selectionlist\""%> 663 onchange="subtypeOnChange()" 664 > 636 665 <% 637 666 if (!readCurrentSubtype) … … 646 675 <option value="0">-none- 647 676 <% 677 int currentSubtypeId = currentSubtype == null ? 0 : currentSubtype.getId(); 648 678 for (ItemSubtype subtype : subtypesQuery.list(dc)) 649 679 { -
trunk/www/biomaterials/samples/index.jsp
r5664 r5686 228 228 sample.setExternalId(Values.getStringOrNull(request.getParameter("external_id"))); 229 229 sample.setOriginalQuantity(Values.getFloat(request.getParameter("original_quantity"), null)); 230 231 int subtypeId = Values.getInt(request.getParameter("subtype_id"), -1); 232 ItemSubtype subtype = null; 233 if (subtypeId >= 0) // < 0 = denied or unchanged 234 { 235 if (subtypeId > 0) subtype = ItemSubtype.getById(dc, subtypeId); 236 sample.setItemSubtype(subtype); 237 if (subtype != null) cc.setRecent(subtype, maxRecent); 238 } 230 239 231 240 BioMaterialEvent creationEvent = sample.getCreationEvent(); … … 239 248 Protocol pt = protocolId == 0 ? null : Protocol.getById(dc, protocolId); 240 249 creationEvent.setProtocol(pt); 241 if (pt != null) cc.setRecent(pt, maxRecent);250 if (pt != null) cc.setRecent(pt, subtype, maxRecent); 242 251 } 243 252 } 244 245 int subtypeId = Values.getInt(request.getParameter("subtype_id"), -1); 246 if (subtypeId >= 0) // < 0 = denied or unchanged 247 { 248 ItemSubtype subtype = subtypeId == 0 ? null : ItemSubtype.getById(dc, subtypeId); 249 sample.setItemSubtype(subtype); 250 if (subtype != null) cc.setRecent(subtype, maxRecent); 251 } 252 253 253 254 int biowellId = Values.getInt(request.getParameter("biowell_id"), -1); 254 255 if (biowellId >= 0) // < 0 = denied or unchanged -
trunk/www/include/scripts/subtypes.js
r5650 r5686 28 28 function ItemSubtypeClass() 29 29 { 30 31 this.cache = new Array(); 32 30 33 /** 31 34 Get the subtype of the given item. … … 62 65 return null; 63 66 } 67 68 // Use cached information if we have it 69 var info = this.cache['ID'+subtypeId]; 70 if (info && info[relatedItemType] && info[relatedItemType].related) 71 { 72 return info[relatedItemType].related; 73 } 74 64 75 var request = Ajax.getXmlHttpRequest(); 65 76 var ID = getSessionId(); … … 97 108 } 98 109 110 this.getRecentAndRelatedInfo = function(subtypeId, mainItemType, relatedItemTypes) 111 { 112 var info = this.cache['ID' + subtypeId]; 113 if (info) 114 { 115 // We have some info already, but... 116 // ...check if we are missing info about some related item types 117 var missingInfo = new Array(); 118 for (var i = 0; i < relatedItemTypes.length; i++) 119 { 120 if (!info[relatedItemTypes[i]]) missingInfo[missingInfo.length] = relatedItemTypes[i]; 121 } 122 relatedItemTypes = missingInfo; 123 } 124 125 // Get more info... 126 if (relatedItemTypes.length > 0) 127 { 128 var request = Ajax.getXmlHttpRequest(); 129 var url = getRoot() + 'admin/itemsubtypes/ajax.jsp?ID=' + getSessionId(); 130 url += '&cmd=GetRecentAndRelated&itemType='+mainItemType; 131 if (subtypeId) 132 { 133 url += '&item_id='+subtypeId; 134 } 135 for (var i = 0; i < relatedItemTypes.length; i++) 136 { 137 url += '&relatedType=' + relatedItemTypes[i]; 138 } 139 request.open("GET", url, false); 140 request.send(null); 141 var moreInfo = JSON.parse(request.responseText); 142 if (!info) 143 { 144 info = moreInfo; 145 } 146 else 147 { 148 // Merge the new info with the existing info 149 for (var i = 0; i < relatedItemTypes.length; i++) 150 { 151 info[relatedItemTypes[i]]= moreInfo[relatedItemTypes[i]]; 152 } 153 } 154 this.cache['ID'+subtypeId] = info; 155 } 156 return info; 157 } 158 159 this.updateRecentItemsInList = function(list, recentItems, noNoneOption) 160 { 161 if (!list || !recentItems) return; 162 163 var oldSelectedValue = list.selectedIndex >= 0 ? list[list.selectedIndex].value : 0; 164 var reselectItemId = 0; 165 166 // Find the current 'recently used' option in the list 167 // It should be the first entry which has a value == 0 168 // ignoring the 'none' option if present 169 var recentHeaderIndex = -1; 170 for (var i = noNoneOption ? 0 : 1; i < list.length; i++) 171 { 172 if (list[i].value == 0) 173 { 174 // Found it -- remove all items below it 175 // but remember the ID of the currently selected 176 // item if it is removed (so we can select it again) 177 recentHeaderIndex = i; 178 if (list.selectedIndex > i) 179 { 180 reselectItemId = list[list.selectedIndex].value; 181 } 182 list.length = i+1; 183 } 184 } 185 186 // If index == -1 we didn't find it so we must add 'recently used' 187 if (recentHeaderIndex == -1) 188 { 189 var recentHeader = new Option('- recently used -', 0); 190 recentHeader.className = 'recentheader'; 191 recentHeader.disabled = true; 192 recentHeaderIndex = list.length; 193 list[recentHeaderIndex] = recentHeader; 194 } 195 196 // Add the new items to the end of the list 197 for (var i = 0; i < recentItems.length; i++) 198 { 199 var selected = reselectItemId == recentItems[i].id; 200 list[list.length] = new Option((i+1) + '. ' + recentItems[i].name, recentItems[i].id, false, selected); 201 } 202 203 // If no item is selected, select the first 'recently used' item. 204 if (list.selectedIndex == 0) 205 { 206 list.selectedIndex = recentHeaderIndex+1; 207 } 208 209 var currentSelectedValue = list.selectedIndex >= 0 ? list[list.selectedIndex].value : 0; 210 return oldSelectedValue != currentSelectedValue; 211 } 99 212 100 213 }
Note: See TracChangeset
for help on using the changeset viewer.