diff --git a/src/main/java/de/bps/olat/modules/cl/ChecklistMultiSelectColumnDescriptor.java b/src/main/java/de/bps/olat/modules/cl/ChecklistMultiSelectColumnDescriptor.java index 7bd4f12fe7898f36aba622b33ae885a826d9ea58..23fcd5838cdbd606b7ce24d42c71300366e29e53 100644 --- a/src/main/java/de/bps/olat/modules/cl/ChecklistMultiSelectColumnDescriptor.java +++ b/src/main/java/de/bps/olat/modules/cl/ChecklistMultiSelectColumnDescriptor.java @@ -19,14 +19,11 @@ */ package de.bps.olat.modules.cl; -import java.util.List; - import org.olat.core.gui.components.table.ColumnDescriptor; import org.olat.core.gui.components.table.HrefGenerator; import org.olat.core.gui.components.table.Table; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; -import org.olat.core.id.Identity; import org.olat.core.logging.AssertException; /** @@ -48,6 +45,11 @@ public class ChecklistMultiSelectColumnDescriptor implements ColumnDescriptor { this.column = column; } + @Override + public int getDataColumn() { + return column; + } + public void renderValue(StringOutput sb, int row, Renderer renderer) { // add checkbox int currentPosInModel = table.getSortedRow(row); diff --git a/src/main/java/de/bps/olat/repository/controllers/RepositorySearchMultiSelectController.java b/src/main/java/de/bps/olat/repository/controllers/RepositorySearchMultiSelectController.java index 31f90a4bedd2e2ac67b63b78507eea2c603b7b0a..bf887d029319fe1b1072587b2bb7a16a1f0239f1 100644 --- a/src/main/java/de/bps/olat/repository/controllers/RepositorySearchMultiSelectController.java +++ b/src/main/java/de/bps/olat/repository/controllers/RepositorySearchMultiSelectController.java @@ -89,7 +89,9 @@ public class RepositorySearchMultiSelectController extends RepositorySearchContr vc.put("searchform",searchForm.getInitialComponent()); TableGuiConfiguration tableConfig = new TableGuiConfiguration(); - if (selectButtonLabel != null) tableConfig.setPreferencesOffered(true, "repositorySearchResult"); + if (selectButtonLabel != null) { + tableConfig.setPreferencesOffered(true, "repositorySearchResult_v2"); + } removeAsListenerAndDispose(tableCtr); tableCtr = new TableController(tableConfig, ureq, getWindowControl(), getTranslator()); diff --git a/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java b/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java index 590c3a4b8ba52322a40129351c29e33b38e62423..b5f6395eff780d34398941c89af73fbb914a0984 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java +++ b/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java @@ -290,40 +290,67 @@ public class ListRenderer { //file metadata as tooltip if (metaInfo != null) { + boolean hasMeta = false; sb.append("<div id='o_sel_doc_tooltip_").append(pos).append("' class='b_ext_tooltip_wrapper b_briefcase_meta' style='display:none;'>"); - if (StringHelper.containsNonWhitespace(metaInfo.getTitle())) { + if (StringHelper.containsNonWhitespace(metaInfo.getTitle())) { String title = StringHelper.escapeHtml(metaInfo.getTitle()); - sb.append("<h5>").append(Formatter.escapeDoubleQuotes(title)).append("</h5>"); + sb.append("<h5>").append(Formatter.escapeDoubleQuotes(title)).append("</h5>"); + hasMeta = true; } if (StringHelper.containsNonWhitespace(metaInfo.getComment())) { + sb.append("<div class=\"b_briefcase_comment\">"); String comment = StringHelper.escapeHtml(metaInfo.getComment()); sb.append(Formatter.escapeDoubleQuotes(comment)); + sb.append("</div>"); + hasMeta = true; } + boolean hasThumbnail = false; if(metaInfo.isThumbnailAvailable()) { sb.append("<div class='b_briefcase_preview' style='width:200px; height:200px; background-image:url("); ubu.buildURI(sb, new String[] { PARAM_SERV_THUMBNAIL}, new String[] { "x" }, pathAndName, AJAXFlags.MODE_NORMAL); sb.append("); background-repeat:no-repeat; background-position:50% 50%;'> </div>"); + hasMeta = true; + hasThumbnail = true; } - String author = metaInfo.getAuthor(); + // first try author info from metadata (creator) + boolean hasMetaAuthor = false; + String author = metaInfo.getCreator(); + // fallback use file author (uploader) if (StringHelper.containsNonWhitespace(author)) { + hasMetaAuthor = true; + } else { + author = metaInfo.getAuthor(); if(!"-".equals(author)) { author = UserManager.getInstance().getUserDisplayName(author); + } else { + author = null; } - sb.append("<p>").append(Formatter.escapeDoubleQuotes(translator.translate("mf.author"))); + + } + if (StringHelper.containsNonWhitespace(author)) { + sb.append("<p class=\"b_briefcase_author\">").append(Formatter.escapeDoubleQuotes(translator.translate("mf.author"))); sb.append(": ").append(Formatter.escapeDoubleQuotes(author)).append("</p>"); + hasMeta = true; + } + sb.append("</div>"); + if (hasMeta) { + // render tooltip only when it contains something + sb.append("<script type='text/javascript'>") + .append("/* <![CDATA[ */") + .append("jQuery(function() {") + .append(" jQuery('#o_sel_doc_").append(pos).append("').tooltip({") + .append(" items: 'a', tooltipClass: 'b_briefcase_meta ") + .append(isContainer ? "b_briefcase_folder " : "b_briefcase_file ") + .append(hasMetaAuthor ? "b_briefcase_with_meta_author " : "b_briefcase_with_uploader_author ") + .append(hasThumbnail ? "b_briefcase_with_thumbnail " : "b_briefcase_without_thumbnail ") + .append("', ") + .append(" content: function(){ return jQuery('#o_sel_doc_tooltip_").append(pos).append("').html(); }") + .append(" });") + .append("});") + .append("/* ]]> */") + .append("</script>"); } - sb.append("</div>") - .append("<script type='text/javascript'>") - .append("/* <![CDATA[ */") - .append("jQuery(function() {") - .append(" jQuery('#o_sel_doc_").append(pos).append("').tooltip({") - .append(" items: 'a',") - .append(" content: function(){ return jQuery('#o_sel_doc_tooltip_").append(pos).append("').html(); }") - .append(" });") - .append("});") - .append("/* ]]> */") - .append("</script>"); } sb.append("</td><td>"); diff --git a/src/main/java/org/olat/core/gui/components/table/ColumnDescriptor.java b/src/main/java/org/olat/core/gui/components/table/ColumnDescriptor.java index ac122d51a25d6e0b30d5208b63c1dc2072df3ffc..cf56e54c1c40e84fd59de9257859cb4e5698c15e 100644 --- a/src/main/java/org/olat/core/gui/components/table/ColumnDescriptor.java +++ b/src/main/java/org/olat/core/gui/components/table/ColumnDescriptor.java @@ -64,6 +64,12 @@ public interface ColumnDescriptor { * renderer, otherwise <code>false</code> */ boolean translateHeaderKey(); + + /** + * Return the index used to retrieve the value in the table model + * @return + */ + public int getDataColumn(); /** * @return diff --git a/src/main/java/org/olat/core/gui/components/table/DefaultColumnDescriptor.java b/src/main/java/org/olat/core/gui/components/table/DefaultColumnDescriptor.java index 976b0aaf312411be3a2ea491dc592e73ec31aaaf..214f2b231cd2c94356afc6861fd1ee73f02b36e9 100644 --- a/src/main/java/org/olat/core/gui/components/table/DefaultColumnDescriptor.java +++ b/src/main/java/org/olat/core/gui/components/table/DefaultColumnDescriptor.java @@ -282,7 +282,8 @@ public class DefaultColumnDescriptor implements ColumnDescriptor { /** * @return int */ - protected int getDataColumn() { + @Override + public int getDataColumn() { return dataColumn; } diff --git a/src/main/java/org/olat/core/gui/components/table/GenericObjectArrayTableDataModel.java b/src/main/java/org/olat/core/gui/components/table/GenericObjectArrayTableDataModel.java index 37071f0d65bd80b3d71fe981e08ef4097e710cf0..3b03827f89aa7406db23ffb5dc84f276d0718378 100644 --- a/src/main/java/org/olat/core/gui/components/table/GenericObjectArrayTableDataModel.java +++ b/src/main/java/org/olat/core/gui/components/table/GenericObjectArrayTableDataModel.java @@ -37,7 +37,7 @@ import java.util.List; * * @author gnaegi */ -public class GenericObjectArrayTableDataModel extends DefaultTableDataModel { +public class GenericObjectArrayTableDataModel extends DefaultTableDataModel<Object[]> { private int columnCount; @@ -45,7 +45,7 @@ public class GenericObjectArrayTableDataModel extends DefaultTableDataModel { * @param objectArrays List of Object[] containing whatever data displayable by the table * @param columnCount Number of elements withing the Object[] */ - public GenericObjectArrayTableDataModel(final List objectArrays, final int columnCount) { + public GenericObjectArrayTableDataModel(final List<Object[]> objectArrays, final int columnCount) { super(objectArrays); this.columnCount = columnCount; } @@ -64,7 +64,7 @@ public class GenericObjectArrayTableDataModel extends DefaultTableDataModel { * third lastModifiedDate */ public final Object getValueAt(final int row, final int col) { - Object[] objectArray = (Object[]) getObject(row); + Object[] objectArray = getObject(row); return objectArray[col]; } @@ -76,7 +76,7 @@ public class GenericObjectArrayTableDataModel extends DefaultTableDataModel { * @param col */ public final void setValueAt(final Object o, final int row, final int col){ - Object[] objectArray = (Object[]) getObject(row); + Object[] objectArray = getObject(row); objectArray[col] = o; } } diff --git a/src/main/java/org/olat/core/gui/components/table/MultiSelectColumnDescriptor.java b/src/main/java/org/olat/core/gui/components/table/MultiSelectColumnDescriptor.java index c6d1de6b56765ec2f543d66f3290c313d1d793ad..49dd905716f0097196f2ae93d228df2483330c9c 100644 --- a/src/main/java/org/olat/core/gui/components/table/MultiSelectColumnDescriptor.java +++ b/src/main/java/org/olat/core/gui/components/table/MultiSelectColumnDescriptor.java @@ -40,7 +40,12 @@ class MultiSelectColumnDescriptor implements ColumnDescriptor { MultiSelectColumnDescriptor(){ //package visibility for constructor } - + + @Override + public int getDataColumn() { + return -1; + } + @Override public void renderValue(final StringOutput sb, final int row, final Renderer renderer) { // add checkbox diff --git a/src/main/java/org/olat/core/gui/components/table/StaticColumnDescriptor.java b/src/main/java/org/olat/core/gui/components/table/StaticColumnDescriptor.java index 047082779d97101b4066cfbffdbb0a5cc85b51b4..b93e5ac12833e659224627bbd54db888e07ba9aa 100644 --- a/src/main/java/org/olat/core/gui/components/table/StaticColumnDescriptor.java +++ b/src/main/java/org/olat/core/gui/components/table/StaticColumnDescriptor.java @@ -86,6 +86,11 @@ public class StaticColumnDescriptor implements ColumnDescriptor { this.translateHeaderKey = translateHeaderKey; } + @Override + public int getDataColumn() { + return -1; + } + /** * @see org.olat.core.gui.components.table.ColumnDescriptor#getAlignment() */ diff --git a/src/main/java/org/olat/core/gui/components/table/Table.java b/src/main/java/org/olat/core/gui/components/table/Table.java index 2450da1fe85670d7b949db535a3cd49e6a425f2d..ee8ea5423eba8d2d82a5964b77e75e3439001a41 100644 --- a/src/main/java/org/olat/core/gui/components/table/Table.java +++ b/src/main/java/org/olat/core/gui/components/table/Table.java @@ -37,6 +37,7 @@ import org.olat.core.gui.components.Component; import org.olat.core.gui.components.ComponentRenderer; import org.olat.core.gui.control.Event; import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.StringOutputPool; import org.olat.core.gui.translator.Translator; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; @@ -180,6 +181,10 @@ public class Table extends Component { protected ColumnDescriptor getColumnDescriptorFromAllCDs(final int column) { return allCDs.get(column); } + + protected int getColumnCountFromAllCDs() { + return allCDs.size(); + } /** * @return Column descriptor of currently sorted column @@ -889,14 +894,14 @@ public class Table extends Component { } } - private void buildFilteredTableDataModel(final String tableSearchString2) { + private void buildFilteredTableDataModel(final String searchString) { List<Object> filteredElementList = new ArrayList<Object>(); log.debug("buildFilteredTableDataModel: tableDataModel.getRowCount()=" + tableDataModel.getRowCount()); if (tableDataModel.getRowCount() > 0) { log.debug("buildFilteredTableDataModel: tableDataModel.getObject(0)=" + tableDataModel.getObject(0)); } for (int row = 0; row < tableDataModel.getRowCount(); row++) { - if (matchRowWithSearchString(row, tableSearchString2)) { + if (matchRowWithSearchString(row, searchString)) { filteredElementList.add(tableDataModel.getObject(row)); } } @@ -916,14 +921,18 @@ public class Table extends Component { return true; } // loop over all columns + TableDataModel unfilteredModel = getUnfilteredTableDataModel(); + Filter htmlFilter = FilterFactory.getHtmlTagsFilter(); - for (int colIndex = 0; colIndex < getUnfilteredTableDataModel().getColumnCount(); colIndex++) { - Object value = getUnfilteredTableDataModel().getValueAt(row, colIndex); - // When a CustomCellRenderer exist, use this to render cell-value to String - ColumnDescriptor cd = this.getColumnDescriptorFromAllCDs(colIndex); - if (isColumnDescriptorVisible(cd)) { + for (int colIndex = getColumnCountFromAllCDs(); colIndex-->0; ) { + ColumnDescriptor cd = getColumnDescriptorFromAllCDs(colIndex); + int dataColumn = cd.getDataColumn(); + if (dataColumn >= 0 && isColumnDescriptorVisible(cd)) { + Object value = unfilteredModel.getValueAt(row, dataColumn); + // When a CustomCellRenderer exist, use this to render cell-value to String if (cd instanceof CustomRenderColumnDescriptor) { - CustomCellRenderer customCellRenderer = ((CustomRenderColumnDescriptor)cd).getCustomCellRenderer(); + CustomRenderColumnDescriptor cdrd = (CustomRenderColumnDescriptor)cd; + CustomCellRenderer customCellRenderer = cdrd.getCustomCellRenderer(); if (customCellRenderer instanceof CustomCssCellRenderer) { // For css renderers only use the hover // text, not the CSS class name and other @@ -934,9 +943,9 @@ public class Table extends Component { continue; } } else { - StringOutput sb = new StringOutput(100); - customCellRenderer.render(sb, null, value, ((CustomRenderColumnDescriptor) cd).getLocale(), cd.getAlignment(), null); - value = sb.toString(); + StringOutput sb = StringOutputPool.allocStringBuilder(250); + customCellRenderer.render(sb, null, value, cdrd.getLocale(), cd.getAlignment(), null); + value = StringOutputPool.freePop(sb); } } @@ -944,10 +953,8 @@ public class Table extends Component { String valueAsString = (String)value; // Remove any HTML markup from the value valueAsString = htmlFilter.filter(valueAsString); - log.debug("matchRowWithFilter: check " + valueAsString); // Finally compare with search value based on a simple lowercase match if (valueAsString.toLowerCase().indexOf(tableSearchString2.toLowerCase()) != -1 ) { - log.debug("matchRowWithFilter: found match for row=" + row + " value=" + valueAsString + " with filter=" + tableSearchString2); return true; } } diff --git a/src/main/java/org/olat/core/gui/components/table/TableController.java b/src/main/java/org/olat/core/gui/components/table/TableController.java index c9126611365447ff32b95ee3832e1a63506c0c7f..ea2d9193e3741eea3fcb7da91ad546a6aac12105 100644 --- a/src/main/java/org/olat/core/gui/components/table/TableController.java +++ b/src/main/java/org/olat/core/gui/components/table/TableController.java @@ -31,8 +31,6 @@ import java.util.BitSet; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Set; -import java.util.TreeSet; import org.olat.core.gui.ShortName; import org.olat.core.gui.UserRequest; @@ -48,19 +46,14 @@ import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.ajax.autocompletion.AutoCompleterController; import org.olat.core.gui.control.generic.ajax.autocompletion.EntriesChosenEvent; import org.olat.core.gui.control.generic.ajax.autocompletion.ListProvider; -import org.olat.core.gui.control.generic.ajax.autocompletion.ListReceiver; import org.olat.core.gui.control.generic.closablewrapper.CloseableCalloutWindowController; import org.olat.core.gui.media.MediaResource; -import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.util.StringHelper; import org.olat.core.util.Util; -import org.olat.core.util.filter.Filter; -import org.olat.core.util.filter.FilterFactory; /** * <!--**************--> @@ -121,8 +114,6 @@ public class TableController extends BasicController { private static final String VC_VAR_HAS_TABLE_SEARCH = "hasTableSearch"; - private static final String LOG_DEBUG_DURATION = " duration="; - private OLog log = Tracing.createLoggerFor(this.getClass()); private static final String CMD_FILTER = "cmd.filter."; @@ -136,10 +127,6 @@ public class TableController extends BasicController { */ public static final Event EVENT_FILTER_SELECTED = new Event("filter.selected"); - /** - * Limit the number of search-suggestions in table-search-popup - */ - private static final int MAX_TABLE_SEARCH_RESULT_ENTRIES = 20; private VelocityContainer contentVc; @@ -303,69 +290,7 @@ public class TableController extends BasicController { } private Controller createTableSearchController(final UserRequest ureq, final WindowControl wControl) { - ListProvider genericProvider = new ListProvider() { - public void getResult(final String searchValue, final ListReceiver receiver) { - Filter htmlFilter = FilterFactory.getHtmlTagsFilter(); - log.debug("getResult start"); - long startTime = System.currentTimeMillis(); - Set<String> searchEntries = new TreeSet<String>(); - int entryCounter = 1; - // loop over whole data-model - for (int rowIndex=0; rowIndex < table.getUnfilteredTableDataModel().getRowCount(); rowIndex++) { - for (int colIndex=0; colIndex < table.getUnfilteredTableDataModel().getColumnCount(); colIndex++) { - Object obj = table.getUnfilteredTableDataModel().getValueAt(rowIndex, colIndex); - // When a CustomCellRenderer exist, use this to render cell-value to String - ColumnDescriptor cd = table.getColumnDescriptorFromAllCDs(colIndex); - if (table.isColumnDescriptorVisible(cd)) { - - if (cd instanceof CustomRenderColumnDescriptor) { - CustomCellRenderer customCellRenderer = ((CustomRenderColumnDescriptor)cd).getCustomCellRenderer(); - if (customCellRenderer instanceof CustomCssCellRenderer) { - // For css renderers only use the hover - // text, not the CSS class name and other - // markup - CustomCssCellRenderer cssRenderer = (CustomCssCellRenderer) customCellRenderer; - obj = cssRenderer.getHoverText(obj); - if (!StringHelper.containsNonWhitespace((String) obj)) { - continue; - } - } else { - StringOutput sb = new StringOutput(); - customCellRenderer.render(sb, null, obj, ((CustomRenderColumnDescriptor) cd).getLocale(), cd.getAlignment(), null); - obj = sb.toString(); - } - } - - if (obj instanceof String) { - String valueString = (String)obj; - // Remove any HTML markup from the value - valueString = htmlFilter.filter(valueString); - // Finally compare with search value based on a simple lowercase match - if (valueString.toLowerCase().indexOf(searchValue.toLowerCase()) != -1) { - if (searchEntries.add(valueString) ) { - // Add to receiver list same entries only once - if (searchEntries.size() == 1) { - // before first entry, add searchValue. But add only when one search match - receiver.addEntry( searchValue, searchValue ); - } - // limit the number of entries - if (entryCounter++ > MAX_TABLE_SEARCH_RESULT_ENTRIES) { - receiver.addEntry("...", "..."); - long duration = System.currentTimeMillis() - startTime; - log.debug("getResult reach MAX_TABLE_SEARCH_RESULT_ENTRIES, entryCounter=" + entryCounter + LOG_DEBUG_DURATION + duration); - return; - } - receiver.addEntry(valueString, valueString); - } - } - } - } - } - } - long duration = System.currentTimeMillis() - startTime; - log.debug("getResult finished entryCounter=" + entryCounter + LOG_DEBUG_DURATION + duration); - } - }; + ListProvider genericProvider = new TableListProvider(table); removeAsListenerAndDispose(tableSearchController); tableSearchController = new AutoCompleterController(ureq, wControl, genericProvider, null, false, 60, 3, translate("table.filter.label")); listenTo(tableSearchController); // TODO:CG 02.09.2010 Test Tablesearch Performance, remove @@ -431,7 +356,7 @@ public class TableController extends BasicController { } private void applyAndcheckChangedColumnsChoice(final UserRequest ureq) { - List selRows = colsChoice.getSelectedRows(); + List<Integer> selRows = colsChoice.getSelectedRows(); if (selRows.size() == 0) { showError("error.selectatleastonecolumn"); } else { @@ -463,17 +388,18 @@ public class TableController extends BasicController { return choice; } + @Override public void event(final UserRequest ureq, final Controller source, final Event event) { log.debug("dispatchEvent event=" + event + " source=" + source); if (event instanceof EntriesChosenEvent) { EntriesChosenEvent ece = (EntriesChosenEvent)event; - List filterList = ece.getEntries(); + List<String> filterList = ece.getEntries(); if (!filterList.isEmpty()) { - this.table.setSearchString((String)filterList.get(0)); - this.modelChanged(false); + table.setSearchString(filterList.get(0)); + modelChanged(false); } else { // reset filter search filter in modelChanged - this.modelChanged(); + modelChanged(); } } } @@ -493,9 +419,7 @@ public class TableController extends BasicController { */ public Object getSortedObjectAt(int sortedRow) { int row = table.getSortedRow(sortedRow); - TableDataModel model = getTableDataModel(); - Object obj = model.getObject(row); - return obj; + return getTableDataModel().getObject(row); } /** @@ -780,5 +704,4 @@ public class TableController extends BasicController { protected void doDispose() { // } - } diff --git a/src/main/java/org/olat/core/gui/components/table/TableListProvider.java b/src/main/java/org/olat/core/gui/components/table/TableListProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..9ec93354c43791aa33239112de97aaebfbd64027 --- /dev/null +++ b/src/main/java/org/olat/core/gui/components/table/TableListProvider.java @@ -0,0 +1,97 @@ +package org.olat.core.gui.components.table; + +import java.util.Set; +import java.util.TreeSet; + +import org.olat.core.gui.control.generic.ajax.autocompletion.ListProvider; +import org.olat.core.gui.control.generic.ajax.autocompletion.ListReceiver; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.StringOutputPool; +import org.olat.core.util.StringHelper; +import org.olat.core.util.filter.Filter; +import org.olat.core.util.filter.FilterFactory; + +/** + * + * Initial date: 05.09.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class TableListProvider implements ListProvider { + + /** + * Limit the number of search-suggestions in table-search-popup + */ + private static final int MAX_TABLE_SEARCH_RESULT_ENTRIES = 20; + + private final Table table; + + public TableListProvider(Table table) { + this.table = table; + } + + @Override + public void getResult(String searchValue, ListReceiver receiver) { + Filter htmlFilter = FilterFactory.getHtmlTagsFilter(); + Set<String> searchEntries = new TreeSet<String>(); + int entryCounter = 1; + // loop over whole data-model + + TableDataModel<?> unfilteredModel = table.getUnfilteredTableDataModel(); + + int rowCount = unfilteredModel.getRowCount(); + int colCount = table.getColumnCountFromAllCDs(); + + a_a: + for (int colIndex=0; colIndex < colCount; colIndex++) { + ColumnDescriptor cd = table.getColumnDescriptorFromAllCDs(colIndex); + int dataColumn = cd.getDataColumn(); + if (dataColumn >= 0 && table.isColumnDescriptorVisible(cd)) { + for (int rowIndex=0; rowIndex < rowCount; rowIndex++) { + Object obj = unfilteredModel.getValueAt(rowIndex, dataColumn); + // When a CustomCellRenderer exist, use this to render cell-value to String + if (cd instanceof CustomRenderColumnDescriptor) { + CustomRenderColumnDescriptor crcd = (CustomRenderColumnDescriptor)cd; + CustomCellRenderer customCellRenderer = crcd.getCustomCellRenderer(); + if (customCellRenderer instanceof CustomCssCellRenderer) { + // For css renderers only use the hover + // text, not the CSS class name and other + // markup + CustomCssCellRenderer cssRenderer = (CustomCssCellRenderer) customCellRenderer; + obj = cssRenderer.getHoverText(obj); + if (!StringHelper.containsNonWhitespace((String) obj)) { + continue; + } + } else { + StringOutput sb = StringOutputPool.allocStringBuilder(250); + customCellRenderer.render(sb, null, obj, crcd.getLocale(), cd.getAlignment(), null); + obj = StringOutputPool.freePop(sb); + } + } + + if (obj instanceof String) { + String valueString = (String)obj; + // Remove any HTML markup from the value + valueString = htmlFilter.filter(valueString); + // Finally compare with search value based on a simple lowercase match + if (valueString.toLowerCase().indexOf(searchValue.toLowerCase()) != -1) { + if (searchEntries.add(valueString) ) { + // Add to receiver list same entries only once + if (searchEntries.size() == 1) { + // before first entry, add searchValue. But add only when one search match + receiver.addEntry( searchValue, searchValue ); + } + // limit the number of entries + if (entryCounter++ > MAX_TABLE_SEARCH_RESULT_ENTRIES) { + receiver.addEntry("...", "..."); + break a_a; + } + receiver.addEntry(valueString, valueString); + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/core/gui/media/ServletUtil.java b/src/main/java/org/olat/core/gui/media/ServletUtil.java index 6e900c4fb66a4514609f2e67a9676fb8e0aebe9a..4bbcd5d696bf86e060254bca687cdaec53aab035 100644 --- a/src/main/java/org/olat/core/gui/media/ServletUtil.java +++ b/src/main/java/org/olat/core/gui/media/ServletUtil.java @@ -207,7 +207,12 @@ public class ServletUtil { FileUtils.closeSafely(in); FileUtils.closeSafely(bis); FileUtils.closeSafely(out); - log.error("client browser probably abort when serving media resource", e); + String className = e.getClass().getSimpleName(); + if("ClientAbortException".equals(className)) { + log.warn("client browser probably abort when serving media resource", e); + } else { + log.error("client browser probably abort when serving media resource", e); + } } } diff --git a/src/main/java/org/olat/course/nodes/ta/ReturnboxController.java b/src/main/java/org/olat/course/nodes/ta/ReturnboxController.java index b4fff711a23b8354df5ed78647aee3223c48518c..929d3a58738d4a6aed856486577b3f7b4dd3c817 100644 --- a/src/main/java/org/olat/course/nodes/ta/ReturnboxController.java +++ b/src/main/java/org/olat/course/nodes/ta/ReturnboxController.java @@ -27,6 +27,7 @@ package org.olat.course.nodes.ta; import java.io.File; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderRunController; import org.olat.core.commons.modules.bc.vfs.OlatNamedContainerImpl; import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; @@ -46,6 +47,7 @@ import org.olat.course.nodes.CourseNode; import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; +import org.olat.user.UserManager; /** * Initial Date: 02.09.2004 @@ -67,6 +69,8 @@ public class ReturnboxController extends BasicController { private SubscriptionContext subsContext; private ContextualSubscriptionController contextualSubscriptionCtr; + private final UserManager userManager; + /** * Implements a dropbox. * @param ureq @@ -82,6 +86,8 @@ public class ReturnboxController extends BasicController { protected ReturnboxController(UserRequest ureq, WindowControl wControl, ModuleConfiguration config, CourseNode node, UserCourseEnvironment userCourseEnv, boolean previewMode, boolean doInit) { super(ureq, wControl); + userManager = CoreSpringFactory.getImpl(UserManager.class); + this.setBasePackage(ReturnboxController.class); if (doInit) { initReturnbox(ureq, wControl, config, node, userCourseEnv, previewMode); @@ -92,7 +98,8 @@ public class ReturnboxController extends BasicController { // returnbox display myContent = createVelocityContainer("returnbox"); OlatRootFolderImpl rootFolder = new OlatRootFolderImpl(getReturnboxPathFor(userCourseEnv.getCourseEnvironment(), node, ureq.getIdentity()) , null); - OlatNamedContainerImpl namedContainer = new OlatNamedContainerImpl(ureq.getIdentity().getName(), rootFolder); + String fullName = userManager.getUserDisplayName(getIdentity()); + OlatNamedContainerImpl namedContainer = new OlatNamedContainerImpl(fullName, rootFolder); namedContainer.setLocalSecurityCallback(new ReadOnlyCallback()); returnboxFolderRunController = new FolderRunController(namedContainer, false, ureq, wControl); returnboxFolderRunController.addControllerListener(this); diff --git a/src/main/java/org/olat/course/nodes/tu/TURequest.java b/src/main/java/org/olat/course/nodes/tu/TURequest.java index 1d5409668d2fe1c91b1833abe8713ecc2879d2d1..78b5daaf6e1202b9efbdf4d8ef8533e8b01e43ac 100644 --- a/src/main/java/org/olat/course/nodes/tu/TURequest.java +++ b/src/main/java/org/olat/course/nodes/tu/TURequest.java @@ -41,7 +41,7 @@ public class TURequest { private String method; private String uri; private String queryString; - private Map parameterMap; + private Map<String,String[]> parameterMap; private String contentType; private String userName, lastName, firstName, email, userIPAddress; @@ -81,7 +81,7 @@ public class TURequest { /** * @return The http request parameter map */ - public Map getParameterMap() { + public Map<String,String[]> getParameterMap() { return parameterMap; } @@ -102,7 +102,7 @@ public class TURequest { /** * @param map */ - public void setParameterMap(Map map) { + public void setParameterMap(Map<String,String[]> map) { parameterMap = map; } @@ -191,7 +191,7 @@ public class TURequest { } public String getUserIPAddress() { - return this.userIPAddress; + return userIPAddress; } public void setUserIPAddress(String address){ diff --git a/src/main/java/org/olat/modules/tu/IframeTunnelController.java b/src/main/java/org/olat/modules/tu/IframeTunnelController.java index a417196d168995556b36ec6b89e07dfd961d7e71..6544f74b1299e823e5d04bcc708978d02e8caf95 100644 --- a/src/main/java/org/olat/modules/tu/IframeTunnelController.java +++ b/src/main/java/org/olat/modules/tu/IframeTunnelController.java @@ -37,6 +37,8 @@ import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; +import org.olat.basesecurity.BaseSecurityModule; +import org.olat.core.CoreSpringFactory; import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -110,7 +112,10 @@ public class IframeTunnelController extends BasicController implements Cloneable String rawurl = TUConfigForm.getFullURL(proto, host, port, startUri, firstQueryString).toString(); myContent.contextPut("url", rawurl); } else { // tunnel + + final Locale loc = ureq.getLocale(); final Identity ident = ureq.getIdentity(); + final String ipAddress = ureq.getUserSession().getSessionInfo().getFromIP(); if (user != null && user.length() > 0) { httpClientInstance = HttpClientFactory.getHttpClientInstance(host, port.intValue(), proto, user, pass); @@ -118,7 +123,6 @@ public class IframeTunnelController extends BasicController implements Cloneable httpClientInstance = HttpClientFactory.getHttpClientInstance(host, port.intValue(), proto, null, null); } - final Locale loc = ureq.getLocale(); Mapper mapper = new Mapper() { public MediaResource handle(String relPath, HttpServletRequest hreq) { MediaResource mr = null; @@ -144,19 +148,18 @@ public class IframeTunnelController extends BasicController implements Cloneable if (queryString != null) cmeth.setQueryString(queryString); meth = cmeth; // if response is a redirect, follow it - if (meth == null) return null; meth.setFollowRedirects(true); } else if (method.equals("POST")) { //if (contentType == null || contentType.equals("application/x-www-form-urlencoded")) { // regular post, no file upload //} - Map params = hreq.getParameterMap(); + Map<String,String[]> params = hreq.getParameterMap(); PostMethod pmeth = new PostMethod(uri); - Set postKeys = params.keySet(); - for (Iterator iter = postKeys.iterator(); iter.hasNext();) { - String key = (String) iter.next(); - String vals[] = (String[]) params.get(key); + Set<String> postKeys = params.keySet(); + for (Iterator<String> iter = postKeys.iterator(); iter.hasNext();) { + String key = iter.next(); + String vals[] = params.get(key); for (int i = 0; i < vals.length; i++) { pmeth.addParameter(key, vals[i]); } @@ -165,17 +168,18 @@ public class IframeTunnelController extends BasicController implements Cloneable if (meth == null) return null; // Redirects are not supported when using POST method! // See RFC 2616, section 10.3.3, page 62 - } - // Add olat specific headers to the request, can be used by external // applications to identify user and to get other params // test page e.g. http://cgi.algonet.se/htbin/cgiwrap/ug/test.py - meth.addRequestHeader("X-OLAT-USERNAME", userName); - meth.addRequestHeader("X-OLAT-LASTNAME", lastName); - meth.addRequestHeader("X-OLAT-FIRSTNAME", firstName); - meth.addRequestHeader("X-OLAT-EMAIL", email); + if("enabled".equals(CoreSpringFactory.getImpl(BaseSecurityModule.class).getUserInfosTunnelCourseBuildingBlock())) { + meth.addRequestHeader("X-OLAT-USERNAME", userName); + meth.addRequestHeader("X-OLAT-LASTNAME", lastName); + meth.addRequestHeader("X-OLAT-FIRSTNAME", firstName); + meth.addRequestHeader("X-OLAT-EMAIL", email); + meth.addRequestHeader("X-OLAT-USERIP", ipAddress); + } boolean ok = false; try { diff --git a/src/main/java/org/olat/modules/tu/TunnelComponent.java b/src/main/java/org/olat/modules/tu/TunnelComponent.java index c02022e97b089c5ed8c601088a6a5f709e53a78d..116db221664653e709f2a1b99743f08c05af18bd 100644 --- a/src/main/java/org/olat/modules/tu/TunnelComponent.java +++ b/src/main/java/org/olat/modules/tu/TunnelComponent.java @@ -47,6 +47,7 @@ import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.render.ValidationResult; import org.olat.core.id.User; import org.olat.core.id.UserConstants; +import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.SimpleHtmlParser; import org.olat.core.util.httpclient.HttpClientFactory; @@ -58,6 +59,7 @@ import org.olat.modules.ModuleConfiguration; * @author Mike Stock Comment: */ public class TunnelComponent extends Component implements AsyncMediaResponsible { + private static final OLog log = Tracing.createLoggerFor(TunnelComponent.class); private static final ComponentRenderer RENDERER = new TunnelRenderer(); private static final String USERAGENT_NAME = "OLAT tunneling module 1.1"; @@ -118,7 +120,7 @@ public class TunnelComponent extends Component implements AsyncMediaResponsible TURequest tureq = new TURequest(); //config, ureq); tureq.setContentType(null); // not used tureq.setMethod("GET"); - tureq.setParameterMap(Collections.EMPTY_MAP); + tureq.setParameterMap(Collections.<String,String[]>emptyMap()); tureq.setQueryString(query); if(startUri != null){ if(startUri.startsWith("/")){ @@ -150,7 +152,7 @@ public class TunnelComponent extends Component implements AsyncMediaResponsible try { body = meth.getResponseBodyAsString(); } catch (IOException e) { - Tracing.logWarn("Problems when tunneling URL::" + tureq.getUri(), e, TunnelComponent.class); + log.warn("Problems when tunneling URL::" + tureq.getUri(), e); htmlContent = "Error: cannot display inline :"+tureq.getUri()+": Unknown transfer problem '"; return; } @@ -233,7 +235,7 @@ public class TunnelComponent extends Component implements AsyncMediaResponsible try { body = meth.getResponseBodyAsString(); } catch (IOException e) { - Tracing.logWarn("Problems when tunneling URL::" + tureq.getUri(), e, TunnelComponent.class); + log.warn("Problems when tunneling URL::" + tureq.getUri(), e); return null; } SimpleHtmlParser parser = new SimpleHtmlParser(body); @@ -274,7 +276,6 @@ public class TunnelComponent extends Component implements AsyncMediaResponsible String queryString = tuReq.getQueryString(); if (queryString != null) cmeth.setQueryString(queryString); meth = cmeth; - if (meth == null) return null; // if response is a redirect, follow it meth.setFollowRedirects(true); @@ -285,10 +286,10 @@ public class TunnelComponent extends Component implements AsyncMediaResponsible } PostMethod pmeth = new PostMethod(modulePath); - Set postKeys = tuReq.getParameterMap().keySet(); - for (Iterator iter = postKeys.iterator(); iter.hasNext();) { - String key = (String) iter.next(); - String vals[] = (String[])tuReq.getParameterMap().get(key); + Set<String> postKeys = tuReq.getParameterMap().keySet(); + for (Iterator<String> iter = postKeys.iterator(); iter.hasNext();) { + String key = iter.next(); + String vals[] = tuReq.getParameterMap().get(key); for (int i = 0; i < vals.length; i++) { pmeth.addParameter(key, vals[i]); } diff --git a/src/main/java/org/olat/modules/tu/TunnelController.java b/src/main/java/org/olat/modules/tu/TunnelController.java index a641e8772fb9a6fa58d22530f3b7e272e759a7a8..8ec7af1c2a99fd5554662ac06a5af11266138c4b 100644 --- a/src/main/java/org/olat/modules/tu/TunnelController.java +++ b/src/main/java/org/olat/modules/tu/TunnelController.java @@ -33,7 +33,7 @@ import org.olat.core.gui.control.DefaultController; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.clone.CloneableController; -import org.olat.core.gui.translator.PackageTranslator; +import org.olat.core.gui.translator.Translator; import org.olat.core.util.Util; import org.olat.modules.ModuleConfiguration; @@ -46,7 +46,6 @@ import org.olat.modules.ModuleConfiguration; * @author gnaegi */ public class TunnelController extends DefaultController implements CloneableController { - private static final String PACKAGE = Util.getPackageName(TunnelController.class); private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(TunnelController.class); private TunnelComponent tuc; @@ -61,7 +60,7 @@ public class TunnelController extends DefaultController implements CloneableCont public TunnelController(UserRequest ureq, WindowControl wControl, ModuleConfiguration config) { super(wControl); this.config = config; - PackageTranslator trans = new PackageTranslator(PACKAGE, ureq.getLocale()); + Translator trans = Util.createPackageTranslator(TunnelController.class, ureq.getLocale()); main = new VelocityContainer("tucMain", VELOCITY_ROOT + "/index.html", trans, null); tuc = new TunnelComponent("tuc", config, ureq); main.put("tuc", tuc); @@ -71,6 +70,7 @@ public class TunnelController extends DefaultController implements CloneableCont /** * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) */ + @Override public void event(UserRequest ureq, Component source, Event event) { // nothing to do } @@ -78,6 +78,7 @@ public class TunnelController extends DefaultController implements CloneableCont /** * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) */ + @Override protected void doDispose() { tuc = null; } @@ -85,6 +86,7 @@ public class TunnelController extends DefaultController implements CloneableCont /** * @see org.olat.core.gui.control.generic.clone.CloneableController#cloneController(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl) */ + @Override public Controller cloneController(UserRequest ureq, WindowControl control) { return new TunnelController(ureq, control, config); } diff --git a/src/main/java/org/olat/repository/controllers/RepositorySearchController.java b/src/main/java/org/olat/repository/controllers/RepositorySearchController.java index 84d65cd3511d33f890353fc7a51928f84c016e01..b5e52a9f0f97dfb6fa9881de207b1cc94dfd40f0 100644 --- a/src/main/java/org/olat/repository/controllers/RepositorySearchController.java +++ b/src/main/java/org/olat/repository/controllers/RepositorySearchController.java @@ -158,7 +158,9 @@ public class RepositorySearchController extends BasicController implements Activ vc.put("searchform",searchForm.getInitialComponent()); TableGuiConfiguration tableConfig = new TableGuiConfiguration(); - if (selectButtonLabel != null) tableConfig.setPreferencesOffered(true, "repositorySearchResult"); + if (selectButtonLabel != null) { + tableConfig.setPreferencesOffered(true, "repositorySearchResult_v2"); + } //fxdiff VCRP-10: repository search with type filter String filterTitle = translator.translate("search.filter.type");