From b60c7e96f4e915837a75e9464c3e7e1e3ba081da Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Fri, 8 Mar 2013 17:38:27 +0100 Subject: [PATCH] OO-535: implements import of QTI 1.2 items, fix issues with d&d... --- .../persistence/_spring/core_persistence.xml | 2 +- .../components/ComponentEventListener.java | 26 ++ .../impl/elements/TextElementImpl.java | 3 +- .../table/FlexiDataTablesRenderer.java | 7 +- .../core/gui/components/tree/MenuTree.java | 9 + .../gui/components/tree/MenuTreeRenderer.java | 6 +- .../core/gui/components/tree/_static/js/dd.js | 17 +- .../course/editor/EditorMainController.java | 1 + src/main/java/org/olat/ims/qti/QTIModule.java | 13 - .../org/olat/ims/qti/_spring/qtiContext.xml | 7 +- .../ItemFileResourceValidator.java | 3 +- .../ims/qti/qpool/QTIImportProcessor.java | 324 ++++++++++++++++++ .../QTIQPoolServiceProvider.java} | 36 +- .../{QuestionPoolSPI.java => QPoolSPI.java} | 6 +- .../org/olat/modules/qpool/QuestionItem.java | 8 +- .../olat/modules/qpool/QuestionItemShort.java | 7 + .../modules/qpool/QuestionPoolModule.java | 23 +- .../qpool/QuestionPoolSPIComparator.java | 4 +- .../modules/qpool/QuestionPoolService.java | 40 ++- .../modules/qpool/_spring/qpoolContext.xml | 7 + ...der.java => FileQPoolServiceProvider.java} | 10 +- ...der.java => TextQPoolServiceProvider.java} | 6 +- .../manager/AbstractQPoolServiceProvider.java | 84 +++++ .../modules/qpool/manager/CollectionDAO.java | 30 +- .../modules/qpool/manager/FileStorage.java | 86 +++++ .../qpool/manager/NullPoolService.java | 2 +- .../olat/modules/qpool/manager/PoolDAO.java | 13 +- .../qpool/manager/QuestionItemDAO.java | 100 +++--- .../manager/QuestionItemDocumentFactory.java | 20 +- .../manager/QuestionPoolServiceImpl.java | 170 ++++----- .../modules/qpool/model/CollectionToItem.java | 2 +- ...ctionImpl.java => ItemCollectionImpl.java} | 6 +- ...onItemDocument.java => QItemDocument.java} | 4 +- ...mController.java => ImportController.java} | 6 +- .../ui/{QuestionItemRow.java => ItemRow.java} | 21 +- .../olat/modules/qpool/ui/ItemRowsSource.java | 2 +- ...ntroller.java => MetadatasController.java} | 4 +- .../{QuestionEvent.java => QItemEvent.java} | 10 +- .../qpool/ui/QuestionItemDataModel.java | 28 +- .../ui/QuestionItemDetailsController.java | 13 +- .../ui/QuestionItemPreviewController.java | 4 +- .../modules/qpool/ui/QuestionItemsSource.java | 4 +- .../qpool/ui/QuestionListController.java | 90 ++--- .../ui/QuestionPoolMainEditorController.java | 15 +- .../qpool/ui/QuestionPoolMenuTreeModel.java | 19 +- .../modules/qpool/ui/QuestionsController.java | 14 +- ...ller.java => TaxonomyAdminController.java} | 8 +- ...dTreeModel.java => TaxonomyTreeModel.java} | 4 +- .../qpool/ui/_content/item_details.html | 1 - .../olat/modules/qpool/ui/_content/items.html | 12 +- .../qpool/ui/_i18n/LocalStrings_de.properties | 1 - .../CollectionOfItemsSource.java | 7 +- .../{ => datasource}/MarkedItemsSource.java | 7 +- .../MyQuestionItemsSource.java | 7 +- .../{ => datasource}/PooledItemsSource.java | 7 +- .../{ => datasource}/SharedItemsSource.java | 7 +- .../edit/EducationalMetadataController.java | 4 +- .../EducationalMetadataEditController.java | 4 +- .../ui/edit/GeneralMetadataController.java | 4 +- .../edit/GeneralMetadataEditController.java | 4 +- .../ui/edit/LifecycleMetadataController.java | 4 +- .../edit/LifecycleMetadataEditController.java | 4 +- .../ui/edit/QuestionMetadataController.java | 23 +- .../edit/QuestionMetadataEditController.java | 23 +- .../ui/edit/RightsMetadataController.java | 4 +- .../ui/edit/RightsMetadataEditController.java | 4 +- .../ui/edit/TechnicalMetadataController.java | 4 +- .../edit/TechnicalMetadataEditController.java | 4 +- .../ImportAuthorBySearchController.java | 2 +- .../ImportAuthorOverviewDataModel.java | 2 +- ...ortAuthorOverviewIdentitiesController.java | 2 +- .../ImportAuthor_1_ChooseMemberStep.java | 8 +- ...mportAuthor_2_ConfirmMemberChoiceStep.java | 2 +- .../{ => wizard}/_content/import_search.html | 0 .../wizard/_i18n/LocalStrings_de.properties | 5 + .../wizard/_i18n/LocalStrings_en.properties | 2 + .../search/service/SearchServiceImpl.java | 4 +- .../service/indexer/QuestionItemIndexer.java | 4 +- .../ims/qti/qpool/QTIImportProcessorTest.java | 144 ++++++++ .../org/olat/ims/qti/qpool/fibi_i_001.xml | 1 + .../org/olat/ims/qti/qpool/mchc_i_002.xml | 1 + .../FileResourceValidatorTest.java | 2 +- .../qpool/manager/CollectionDAOTest.java | 25 +- .../modules/qpool/manager/PoolDAOTest.java | 20 +- .../qpool/manager/QuestionDAOTest.java | 68 ++-- .../manager/QuestionPoolServiceTest.java | 44 ++- .../modules/qpool/manager/mchc_asmimr_101.xml | 1 + .../olat/modules/qpool/manager/mchc_i_001.xml | 2 +- 88 files changed, 1303 insertions(+), 495 deletions(-) rename src/main/java/org/olat/ims/qti/{fileresource => qpool}/ItemFileResourceValidator.java (98%) create mode 100644 src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java rename src/main/java/org/olat/ims/qti/{QTIQuestionPoolServiceProvider.java => qpool/QTIQPoolServiceProvider.java} (66%) rename src/main/java/org/olat/modules/qpool/{QuestionPoolSPI.java => QPoolSPI.java} (90%) rename src/main/java/org/olat/modules/qpool/impl/{PdfQuestionPoolServiceProvider.java => FileQPoolServiceProvider.java} (87%) rename src/main/java/org/olat/modules/qpool/impl/{TextQuestionPoolServiceProvider.java => TextQPoolServiceProvider.java} (90%) create mode 100644 src/main/java/org/olat/modules/qpool/manager/AbstractQPoolServiceProvider.java create mode 100644 src/main/java/org/olat/modules/qpool/manager/FileStorage.java rename src/main/java/org/olat/modules/qpool/model/{QuestionItemCollectionImpl.java => ItemCollectionImpl.java} (94%) rename src/main/java/org/olat/modules/qpool/model/{QuestionItemDocument.java => QItemDocument.java} (91%) rename src/main/java/org/olat/modules/qpool/ui/{ImportQuestionItemController.java => ImportController.java} (92%) rename src/main/java/org/olat/modules/qpool/ui/{QuestionItemRow.java => ItemRow.java} (92%) rename src/main/java/org/olat/modules/qpool/ui/{QuestionItemMetadatasController.java => MetadatasController.java} (98%) rename src/main/java/org/olat/modules/qpool/ui/{QuestionEvent.java => QItemEvent.java} (83%) rename src/main/java/org/olat/modules/qpool/ui/{StudyFieldAdminController.java => TaxonomyAdminController.java} (88%) rename src/main/java/org/olat/modules/qpool/ui/{StudyFieldTreeModel.java => TaxonomyTreeModel.java} (96%) rename src/main/java/org/olat/modules/qpool/ui/{ => datasource}/CollectionOfItemsSource.java (88%) rename src/main/java/org/olat/modules/qpool/ui/{ => datasource}/MarkedItemsSource.java (86%) rename src/main/java/org/olat/modules/qpool/ui/{ => datasource}/MyQuestionItemsSource.java (86%) rename src/main/java/org/olat/modules/qpool/ui/{ => datasource}/PooledItemsSource.java (87%) rename src/main/java/org/olat/modules/qpool/ui/{ => datasource}/SharedItemsSource.java (88%) rename src/main/java/org/olat/modules/qpool/ui/{ => wizard}/ImportAuthorBySearchController.java (98%) rename src/main/java/org/olat/modules/qpool/ui/{ => wizard}/ImportAuthorOverviewDataModel.java (98%) rename src/main/java/org/olat/modules/qpool/ui/{ => wizard}/ImportAuthorOverviewIdentitiesController.java (99%) rename src/main/java/org/olat/modules/qpool/ui/{ => wizard}/ImportAuthor_1_ChooseMemberStep.java (92%) rename src/main/java/org/olat/modules/qpool/ui/{ => wizard}/ImportAuthor_2_ConfirmMemberChoiceStep.java (97%) rename src/main/java/org/olat/modules/qpool/ui/{ => wizard}/_content/import_search.html (100%) create mode 100644 src/main/java/org/olat/modules/qpool/ui/wizard/_i18n/LocalStrings_de.properties create mode 100644 src/main/java/org/olat/modules/qpool/ui/wizard/_i18n/LocalStrings_en.properties create mode 100644 src/test/java/org/olat/ims/qti/qpool/QTIImportProcessorTest.java create mode 100644 src/test/java/org/olat/ims/qti/qpool/fibi_i_001.xml create mode 100644 src/test/java/org/olat/ims/qti/qpool/mchc_i_002.xml create mode 100644 src/test/java/org/olat/modules/qpool/manager/mchc_asmimr_101.xml diff --git a/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml b/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml index 4991a45fcd2..ac4478a8eba 100644 --- a/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml +++ b/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml @@ -101,7 +101,7 @@ <class>org.olat.modules.qpool.model.ResourceShareImpl</class> <class>org.olat.modules.qpool.model.TaxonomyLevelImpl</class> <class>org.olat.modules.qpool.model.ResourceShareImpl</class> - <class>org.olat.modules.qpool.model.QuestionItemCollectionImpl</class> + <class>org.olat.modules.qpool.model.ItemCollectionImpl</class> <class>org.olat.modules.qpool.model.CollectionToItem</class> <properties> <property name="hibernate.generate_statistics" value="true"/> diff --git a/src/main/java/org/olat/core/gui/components/ComponentEventListener.java b/src/main/java/org/olat/core/gui/components/ComponentEventListener.java index f03a962ed44..9cf5062162d 100644 --- a/src/main/java/org/olat/core/gui/components/ComponentEventListener.java +++ b/src/main/java/org/olat/core/gui/components/ComponentEventListener.java @@ -1,8 +1,34 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.core.gui.components; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Event; + +/** + * + * Initial date: 07.03.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ public interface ComponentEventListener { /** diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementImpl.java index 7306c95b4fe..d9c4ac9820e 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementImpl.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementImpl.java @@ -48,6 +48,7 @@ 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.ValidationStatus; /** * Description:<br> @@ -288,7 +289,7 @@ public class TextElementImpl extends AbstractTextElement implements InlineTextEl //validate the inline element to check for error transientValue = getValue(); setValue(paramVal); - validate(new ArrayList()); + validate(new ArrayList<ValidationStatus>()); if(hasError()){ //in any case, if an error is there -> set Inline Editing on isInlineEditingOn(true); diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiDataTablesRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiDataTablesRenderer.java index db7f62d01fd..166476b5951 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiDataTablesRenderer.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/FlexiDataTablesRenderer.java @@ -60,7 +60,7 @@ class FlexiDataTablesRenderer extends AbstractFlexiTableRenderer implements Comp String id = ftC.getFormDispatchId(); int rows = dataModel.getRowCount(); - target.append("<script>") + target.append("<script type='text/javascript'>") .append("jQuery(function() {\n") .append(" jQuery('#").append(id).append("').dataTable( {\n") .append(" 'bScrollInfinite': true,\n") @@ -75,10 +75,11 @@ class FlexiDataTablesRenderer extends AbstractFlexiTableRenderer implements Comp .append(" 'fnRowCallback': function( nRow, aData, iDisplayIndex ) {\n") .append(" jQuery(nRow).draggable({ \n") .append(" containment: '#b_main',\n") + .append(" zIndex: 10000,\n") .append(" cursorAt: {left: 0, top: 0},\n") - .append(" accept: function(event,ui){ console.log('Accept'); return true; },\n") + .append(" accept: function(event,ui){ return true; },\n") .append(" helper: function(event) {\n") - .append(" return jQuery(\"<div class='ui-widget-header' style='z-index:1000;'>I'm a custom helper</div>\");\n") + .append(" return jQuery(\"<div class='ui-widget-header'>I'm a custom helper</div>\").appendTo('body').css('zIndex',5).show();\n") .append(" }\n") .append(" });\n") .append(" },\n") diff --git a/src/main/java/org/olat/core/gui/components/tree/MenuTree.java b/src/main/java/org/olat/core/gui/components/tree/MenuTree.java index 92228677d4c..4d881354073 100644 --- a/src/main/java/org/olat/core/gui/components/tree/MenuTree.java +++ b/src/main/java/org/olat/core/gui/components/tree/MenuTree.java @@ -108,6 +108,7 @@ public class MenuTree extends Component { private boolean expandServerOnly = true; // default is serverside menu private boolean dragEnabled = false; private boolean dropEnabled = false; + private boolean dropSiblingEnabled = false; private boolean expandSelectedNode = true; private boolean rootVisible = true; //fxdiff VCRP-9: drag and drop in menu tree @@ -421,6 +422,14 @@ public class MenuTree extends Component { dropEnabled = enabled; } + public boolean isDropSiblingEnabled() { + return dropSiblingEnabled; + } + + public void setDropSiblingEnabled(boolean enabled) { + dropSiblingEnabled = enabled; + } + /** * @return The group of drag and drop (cannot be null). */ diff --git a/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java b/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java index 4c2ce4d5d0a..517e6f58f14 100644 --- a/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java +++ b/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java @@ -145,7 +145,7 @@ public class MenuTreeRenderer implements ComponentRenderer { } String ident = curRoot.getIdent(); target.append("\"><div id='dd").append(ident).append("' class=\"b_tree_item_wrapper"); - if(tree.isDragEnabled()) { + if(tree.isDragEnabled() || tree.isDropEnabled()) { target.append(" b_dd_item"); } if(selected) { @@ -283,7 +283,7 @@ public class MenuTreeRenderer implements ComponentRenderer { target.append("</div>"); //append div to drop as sibling - if(!renderChildren && (tree.isDragEnabled() || tree.isDropEnabled())) { + if(!renderChildren && (tree.isDragEnabled() || tree.isDropSiblingEnabled())) { appendSiblingDropObj(curRoot, level, tree, target, ubu, flags, false); } @@ -292,7 +292,7 @@ public class MenuTreeRenderer implements ComponentRenderer { renderChildren(target, level, curRoot, selPath, openNodeIds, ubu, flags, markedNode, tree); //append div to drop as sibling after the children - if(tree.isDragEnabled() || tree.isDropEnabled()) { + if(tree.isDragEnabled() || tree.isDropSiblingEnabled()) { appendSiblingDropObj(curRoot, level, tree, target, ubu, flags, true); } } diff --git a/src/main/java/org/olat/core/gui/components/tree/_static/js/dd.js b/src/main/java/org/olat/core/gui/components/tree/_static/js/dd.js index 30670037de3..fd484e6794c 100644 --- a/src/main/java/org/olat/core/gui/components/tree/_static/js/dd.js +++ b/src/main/java/org/olat/core/gui/components/tree/_static/js/dd.js @@ -42,14 +42,15 @@ function treeAcceptDrop(el) { return false; } - var dropAllowed = dropEl.data(dragNodeId); + var sibling = ""; + if(dropElId.indexOf('ds') == 0) { + sibling = "yes"; + } else if(dropElId.indexOf('dt') == 0) { + sibling = "end"; + } + + var dropAllowed = dropEl.data(dragNodeId + "-" + sibling); if(dropAllowed === undefined) { - var sibling = ""; - if(dragElId.indexOf('ds') == 0) { - sibling = "yes"; - } else if(dragElId.indexOf('dt') == 0) { - sibling = "end"; - } var url = dropEl.droppable('option', 'fbUrl'); //use prototype for the Ajax call jQuery.ajax(url, { @@ -61,7 +62,7 @@ function treeAcceptDrop(el) { dropAllowed = data.dropAllowed; } }); - dropEl.data(dragNodeId, dropAllowed); + dropEl.data(dragNodeId + "-" + sibling, dropAllowed); } return dropAllowed; } diff --git a/src/main/java/org/olat/course/editor/EditorMainController.java b/src/main/java/org/olat/course/editor/EditorMainController.java index 7255d1ddf69..a7970093138 100644 --- a/src/main/java/org/olat/course/editor/EditorMainController.java +++ b/src/main/java/org/olat/course/editor/EditorMainController.java @@ -263,6 +263,7 @@ public class EditorMainController extends MainLayoutBasicController implements G //fxdiff VCRP-9: drag and drop in menu tree menuTree.setDragEnabled(true); menuTree.setDropEnabled(true); + menuTree.setDropSiblingEnabled(true); menuTree.setDragAndDropGroup("courseEditorGroup"); diff --git a/src/main/java/org/olat/ims/qti/QTIModule.java b/src/main/java/org/olat/ims/qti/QTIModule.java index 50810ad08f7..a6108c17d9d 100644 --- a/src/main/java/org/olat/ims/qti/QTIModule.java +++ b/src/main/java/org/olat/ims/qti/QTIModule.java @@ -29,7 +29,6 @@ import java.util.List; import org.olat.core.configuration.AbstractOLATModule; import org.olat.core.configuration.PersistedProperties; -import org.olat.modules.qpool.QuestionPoolModule; import org.olat.repository.handlers.RepositoryHandler; import org.olat.repository.handlers.RepositoryHandlerFactory; @@ -42,7 +41,6 @@ public class QTIModule extends AbstractOLATModule { private static boolean isValidating = false; private static final String CONFIG_VALIDATING = "validating"; private List<RepositoryHandler> qtiRepositoryHandlers; - private QuestionPoolModule poolModule; /** * @return true if qti xml files should be validated @@ -62,8 +60,6 @@ public class QTIModule extends AbstractOLATModule { for (RepositoryHandler qtiRepositoryHandler : qtiRepositoryHandlers) { RepositoryHandlerFactory.registerHandler(qtiRepositoryHandler); } - - poolModule.addQuestionPoolProvider(new QTIQuestionPoolServiceProvider()); } @Override @@ -76,21 +72,12 @@ public class QTIModule extends AbstractOLATModule { protected void initFromChangedProperties() { // } - - /** - * [used by Spring] - * @param poolModule - */ - public void setPoolModule(QuestionPoolModule poolModule) { - this.poolModule = poolModule; - } @Override public void setPersistedProperties(PersistedProperties persistedProperties) { this.moduleConfigProperties = persistedProperties; } - /** * [SPRING] * @param qtiFileHandlers diff --git a/src/main/java/org/olat/ims/qti/_spring/qtiContext.xml b/src/main/java/org/olat/ims/qti/_spring/qtiContext.xml index 4f419ea149c..0971732541f 100644 --- a/src/main/java/org/olat/ims/qti/_spring/qtiContext.xml +++ b/src/main/java/org/olat/ims/qti/_spring/qtiContext.xml @@ -1,13 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.2.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.2.xsd"> + <context:component-scan base-package="org.olat.ims.qti.qpool" /> <bean id="qtiModule" class="org.olat.ims.qti.QTIModule" depends-on="database" > - <property name="poolModule" ref="qpoolModule"/> <property name="qtiRepositoryHandlers"> <list> <ref bean="QTITestHandler${assessmentplugin.activate}" /> diff --git a/src/main/java/org/olat/ims/qti/fileresource/ItemFileResourceValidator.java b/src/main/java/org/olat/ims/qti/qpool/ItemFileResourceValidator.java similarity index 98% rename from src/main/java/org/olat/ims/qti/fileresource/ItemFileResourceValidator.java rename to src/main/java/org/olat/ims/qti/qpool/ItemFileResourceValidator.java index afd27c2a787..3524c898a0c 100644 --- a/src/main/java/org/olat/ims/qti/fileresource/ItemFileResourceValidator.java +++ b/src/main/java/org/olat/ims/qti/qpool/ItemFileResourceValidator.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.ims.qti.fileresource; +package org.olat.ims.qti.qpool; import java.io.File; import java.io.FileInputStream; @@ -148,6 +148,7 @@ public class ItemFileResourceValidator { @Override public void error(SAXParseException exception) throws SAXException { + exception.printStackTrace(); error++; } diff --git a/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java b/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java new file mode 100644 index 00000000000..0037c517343 --- /dev/null +++ b/src/main/java/org/olat/ims/qti/qpool/QTIImportProcessor.java @@ -0,0 +1,324 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.ims.qti.qpool; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.apache.commons.io.IOUtils; +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.Element; +import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.StringHelper; +import org.olat.core.util.xml.XMLParser; +import org.olat.ims.qti.QTIConstants; +import org.olat.ims.qti.editor.beecom.parser.ItemParser; +import org.olat.ims.resources.IMSEntityResolver; +import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionType; +import org.olat.modules.qpool.manager.FileStorage; +import org.olat.modules.qpool.manager.QuestionItemDAO; +import org.olat.modules.qpool.model.QuestionItemImpl; + +/** + * This class is NOT thread-safe + * + * Initial date: 07.03.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +class QTIImportProcessor { + + private static final OLog log = Tracing.createLoggerFor(QTIImportProcessor.class); + + private final Identity owner; + private final String importedFilename; + private final File importedFile; + private final QuestionItemDAO questionItemDao; + + + public QTIImportProcessor(Identity owner, String importedFilename, File importedFile, QuestionItemDAO questionItemDao) { + this.owner = owner; + this.importedFilename = importedFilename; + this.importedFile = importedFile; + this.questionItemDao = questionItemDao; + } + + public List<QuestionItem> process() { + List<QuestionItem> qItems = new ArrayList<QuestionItem>(); + try { + DocInfos docInfos = getDocInfos(); + if(docInfos != null && docInfos.doc != null) { + List<ItemInfos> itemElements = getItemList(docInfos); + for(ItemInfos itemElement:itemElements) { + QuestionItem qItem = processItem(itemElement); + if(qItem != null) { + qItems.add(qItem); + } + + } + } + + /* + VFSLeaf leaf = itemDir.createChildLeaf(filename); + OutputStream out = leaf.getOutputStream(false); + InputStream in = null; + try { + in = new FileInputStream(file); + IOUtils.copy(in, out); + } catch (FileNotFoundException e) { + log.error("", e); + } catch (IOException e) { + log.error("", e); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + } + */ + } catch (IOException e) { + log.error("", e); + } + return qItems; + } + + protected List<ItemInfos> getItemList(DocInfos doc) { + Document document = doc.getDocument(); + List<ItemInfos> itemElements = new ArrayList<ItemInfos>(); + Element item = (Element)document.selectSingleNode("/questestinterop/item"); + Element assessment = (Element)document.selectSingleNode("/questestinterop/assessment"); + if(item != null) { + ItemInfos itemInfos = new ItemInfos(item); + Element comment = (Element)document.selectSingleNode("/questestinterop/qticomment"); + String qtiComment = getText(comment); + itemInfos.setComment(qtiComment); + itemElements.add(itemInfos); + } else if(document.matches("/questestinterop/assessment")) { + @SuppressWarnings("unchecked") + List<Element> items = assessment.selectNodes("//item"); + for(Element it:items) { + itemElements.add(new ItemInfos(it)); + } + } + return itemElements; + } + + protected QuestionItem processItem(ItemInfos itemInfos) { + Element itemEl = itemInfos.getItemEl(); + //filename + String filename; + String ident = getAttributeValue(itemEl, "ident"); + if(StringHelper.containsNonWhitespace(ident)) { + filename = StringHelper.transformDisplayNameToFileSystemName(ident) + ".xml"; + } else { + filename = "item.xml"; + } + String dir = FileStorage.generateDir(); + + //title + String title = getAttributeValue(itemEl, "title"); + if(!StringHelper.containsNonWhitespace(title)) { + title = ident; + } + if(!StringHelper.containsNonWhitespace(title)) { + title = importedFilename; + } + QuestionItemImpl poolItem = questionItemDao.create(title, QTIConstants.QTI_12_FORMAT, dir, filename); + //description + poolItem.setDescription(itemInfos.getComment()); + + //question type: mc, sc... + QuestionType type = null; + //test with openolat ident + if (ident != null && ident.startsWith(ItemParser.ITEM_PREFIX_SCQ)) { + type = QuestionType.SC; + } else if(ident != null && ident.startsWith(ItemParser.ITEM_PREFIX_MCQ)) { + type = QuestionType.MC; + } else if(ident != null && ident.startsWith(ItemParser.ITEM_PREFIX_FIB)) { + type = QuestionType.FIB; + } else if(ident != null && ident.startsWith(ItemParser.ITEM_PREFIX_ESSAY)) { + type = QuestionType.ESSAY; + } else if(ident != null && ident.startsWith(ItemParser.ITEM_PREFIX_KPRIM)) { + type = QuestionType.KPRIM; + } else if(itemEl.selectNodes("//render_choice").size() == 1) { + Element lidEl = (Element)itemEl.selectSingleNode("//response_lid"); + String rcardinality = getAttributeValue(lidEl, "rcardinality"); + if("Single".equals(rcardinality)) { + type = QuestionType.SC; + } else if("Multiple".equals(rcardinality)) { + type = QuestionType.MC; + } + } else if(itemEl.selectNodes("//render_fib").size() == 1) { + type = QuestionType.FIB; + } + if(type != null) { + poolItem.setType(type.name()); + } + questionItemDao.persist(owner, poolItem); + return poolItem; + } + + private String getAttributeValue(Element el, String attrName) { + if(el == null) return null; + Attribute attr = el.attribute(attrName); + return (attr == null) ? null : attr.getStringValue(); + } + + private String getText(Element el) { + if(el == null) return null; + return el.getText(); + } + + protected DocInfos getDocInfos() throws IOException { + DocInfos doc; + if(importedFilename.toLowerCase().endsWith(".zip")) { + doc = traverseZip(importedFile); + } else { + doc = traverseFile(importedFile); + } + return doc; + } + + private DocInfos traverseFile(File file) throws IOException { + InputStream in = new FileInputStream(file); + try { + Document doc = readXml(in); + if(doc != null) { + DocInfos d = new DocInfos(); + d.doc = doc; + d.filename = file.getName(); + return d; + } + return null; + } catch(Exception e) { + log.error("", e); + return null; + } finally { + IOUtils.closeQuietly(in); + } + } + + private DocInfos traverseZip(File file) throws IOException { + InputStream in = new FileInputStream(file); + ZipInputStream zis = new ZipInputStream(in); + + ZipEntry entry; + try { + while ((entry = zis.getNextEntry()) != null) { + String name = entry.getName(); + if(name != null && name.toLowerCase().equals(".xml")) { + Document doc = readXml(in); + if(doc != null) { + DocInfos d = new DocInfos(); + d.doc = doc; + d.filename = name; + return d; + } + } + } + return null; + } catch(Exception e) { + log.error("", e); + return null; + } finally { + IOUtils.closeQuietly(zis); + IOUtils.closeQuietly(in); + } + } + + private Document readXml(InputStream in) { + Document doc = null; + try { + XMLParser xmlParser = new XMLParser(new IMSEntityResolver()); + doc = xmlParser.parse(in, false); + in.close(); + return doc; + } catch (Exception e) { + return null; + } + } + + public static class ItemInfos { + private Element itemEl; + private String comment; + + public ItemInfos() { + // + } + + public ItemInfos(Element itemEl) { + this.itemEl = itemEl; + } + + public Element getItemEl() { + return itemEl; + } + + public void setItemEl(Element itemEl) { + this.itemEl = itemEl; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + } + + public static class DocInfos { + private String filename; + private Document doc; + private String qtiComment; + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public Document getDocument() { + return doc; + } + + public void setDocument(Document doc) { + this.doc = doc; + } + + public String getQtiComment() { + return qtiComment; + } + + public void setQtiComment(String qtiComment) { + this.qtiComment = qtiComment; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/ims/qti/QTIQuestionPoolServiceProvider.java b/src/main/java/org/olat/ims/qti/qpool/QTIQPoolServiceProvider.java similarity index 66% rename from src/main/java/org/olat/ims/qti/QTIQuestionPoolServiceProvider.java rename to src/main/java/org/olat/ims/qti/qpool/QTIQPoolServiceProvider.java index 807ea9e54b8..e8ad5327f41 100644 --- a/src/main/java/org/olat/ims/qti/QTIQuestionPoolServiceProvider.java +++ b/src/main/java/org/olat/ims/qti/qpool/QTIQPoolServiceProvider.java @@ -17,17 +17,23 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.ims.qti; +package org.olat.ims.qti.qpool; import java.io.File; +import java.util.List; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; +import org.olat.core.id.Identity; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.ims.qti.fileresource.ItemFileResourceValidator; +import org.olat.ims.qti.QTI12PreviewController; +import org.olat.ims.qti.QTIConstants; +import org.olat.modules.qpool.QPoolSPI; import org.olat.modules.qpool.QuestionItem; -import org.olat.modules.qpool.QuestionPoolSPI; +import org.olat.modules.qpool.manager.QuestionItemDAO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * @@ -35,7 +41,15 @@ import org.olat.modules.qpool.QuestionPoolSPI; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class QTIQuestionPoolServiceProvider implements QuestionPoolSPI { +@Service("qtiPoolServiceProvider") +public class QTIQPoolServiceProvider implements QPoolSPI { + + @Autowired + private QuestionItemDAO questionItemDao; + + public QTIQPoolServiceProvider() { + // + } @Override public int getPriority() { @@ -49,11 +63,19 @@ public class QTIQuestionPoolServiceProvider implements QuestionPoolSPI { @Override public boolean isCompatible(String filename, File file) { - return new ItemFileResourceValidator().validate(filename, file); + boolean ok = new ItemFileResourceValidator().validate(filename, file); + return ok; } @Override public boolean isCompatible(String filename, VFSLeaf file) { - return new ItemFileResourceValidator().validate(filename, file); + boolean ok = new ItemFileResourceValidator().validate(filename, file); + return ok; + } + + @Override + public List<QuestionItem> importItems(Identity owner, String filename, File file) { + QTIImportProcessor processor = new QTIImportProcessor(owner, filename, file, questionItemDao); + return processor.process(); } @Override @@ -67,4 +89,6 @@ public class QTIQuestionPoolServiceProvider implements QuestionPoolSPI { QTI12PreviewController previewCtrl = new QTI12PreviewController(ureq, wControl, item); return previewCtrl; } + + } \ No newline at end of file diff --git a/src/main/java/org/olat/modules/qpool/QuestionPoolSPI.java b/src/main/java/org/olat/modules/qpool/QPoolSPI.java similarity index 90% rename from src/main/java/org/olat/modules/qpool/QuestionPoolSPI.java rename to src/main/java/org/olat/modules/qpool/QPoolSPI.java index 877e85b0667..842d9af5cf1 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionPoolSPI.java +++ b/src/main/java/org/olat/modules/qpool/QPoolSPI.java @@ -20,10 +20,12 @@ package org.olat.modules.qpool; import java.io.File; +import java.util.List; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; +import org.olat.core.id.Identity; import org.olat.core.util.vfs.VFSLeaf; /** @@ -32,7 +34,7 @@ import org.olat.core.util.vfs.VFSLeaf; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public interface QuestionPoolSPI { +public interface QPoolSPI { public int getPriority(); @@ -42,6 +44,8 @@ public interface QuestionPoolSPI { public boolean isCompatible(String filename, VFSLeaf file); + public List<QuestionItem> importItems(Identity owner, String filename, File file); + public Controller getPreviewController(UserRequest ureq, WindowControl wControl, QuestionItem item); public Controller getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem item); diff --git a/src/main/java/org/olat/modules/qpool/QuestionItem.java b/src/main/java/org/olat/modules/qpool/QuestionItem.java index aa480f4e25a..bae7ba8422f 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionItem.java +++ b/src/main/java/org/olat/modules/qpool/QuestionItem.java @@ -42,13 +42,7 @@ public interface QuestionItem extends QuestionItemShort { * @return */ public String getTaxonomicPath(); - - /** - * Field can be lazy loaded - * @return - */ - public String getTaxonomyLevelName(); - + //question public String getAssessmentType(); diff --git a/src/main/java/org/olat/modules/qpool/QuestionItemShort.java b/src/main/java/org/olat/modules/qpool/QuestionItemShort.java index 7180772df1a..1cec328c3d7 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionItemShort.java +++ b/src/main/java/org/olat/modules/qpool/QuestionItemShort.java @@ -43,6 +43,13 @@ public interface QuestionItemShort extends OLATResourceable { public String getLanguage(); + //classification + /** + * Field can be lazy loaded + * @return + */ + public String getTaxonomyLevelName(); + //educational public String getEducationalContext(); diff --git a/src/main/java/org/olat/modules/qpool/QuestionPoolModule.java b/src/main/java/org/olat/modules/qpool/QuestionPoolModule.java index 9f4485b891f..e53716afefd 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionPoolModule.java +++ b/src/main/java/org/olat/modules/qpool/QuestionPoolModule.java @@ -29,8 +29,6 @@ import org.olat.core.configuration.AbstractOLATModule; import org.olat.core.configuration.ConfigOnOff; import org.olat.core.configuration.PersistedProperties; import org.olat.core.util.vfs.VFSContainer; -import org.olat.modules.qpool.impl.PdfQuestionPoolServiceProvider; -import org.olat.modules.qpool.impl.TextQuestionPoolServiceProvider; /** * @@ -40,14 +38,13 @@ import org.olat.modules.qpool.impl.TextQuestionPoolServiceProvider; */ public class QuestionPoolModule extends AbstractOLATModule implements ConfigOnOff { - private final List<QuestionPoolSPI> questionPoolProviders = new ArrayList<QuestionPoolSPI>(); + private final List<QPoolSPI> questionPoolProviders = new ArrayList<QPoolSPI>(); private VFSContainer rootContainer; @Override public void init() { - addQuestionPoolProvider(new TextQuestionPoolServiceProvider()); - addQuestionPoolProvider(new PdfQuestionPoolServiceProvider()); + // } @Override @@ -77,22 +74,22 @@ public class QuestionPoolModule extends AbstractOLATModule implements ConfigOnOf return rootContainer; } - public List<QuestionPoolSPI> getQuestionPoolProviders() { - List<QuestionPoolSPI> providers = new ArrayList<QuestionPoolSPI>(questionPoolProviders); + public List<QPoolSPI> getQuestionPoolProviders() { + List<QPoolSPI> providers = new ArrayList<QPoolSPI>(questionPoolProviders); Collections.sort(providers, new QuestionPoolSPIComparator()); return providers; } - public void setQuestionPoolProviders(List<QuestionPoolSPI> providers) { + public void setQuestionPoolProviders(List<QPoolSPI> providers) { if(providers != null) { - for(QuestionPoolSPI provider:providers) { + for(QPoolSPI provider:providers) { addQuestionPoolProvider(provider); } } } - public QuestionPoolSPI getQuestionPoolProvider(String format) { - for(QuestionPoolSPI provider:questionPoolProviders) { + public QPoolSPI getQuestionPoolProvider(String format) { + for(QPoolSPI provider:questionPoolProviders) { if(format.equals(provider.getFormat())) { return provider; } @@ -100,10 +97,10 @@ public class QuestionPoolModule extends AbstractOLATModule implements ConfigOnOf return null; } - public void addQuestionPoolProvider(QuestionPoolSPI provider) { + public void addQuestionPoolProvider(QPoolSPI provider) { int currentIndex = -1; for(int i=questionPoolProviders.size(); i-->0; ) { - QuestionPoolSPI currentProvider = questionPoolProviders.get(i); + QPoolSPI currentProvider = questionPoolProviders.get(i); if(provider.getFormat() != null && provider.getFormat().equals(currentProvider.getFormat())) { currentIndex = i; diff --git a/src/main/java/org/olat/modules/qpool/QuestionPoolSPIComparator.java b/src/main/java/org/olat/modules/qpool/QuestionPoolSPIComparator.java index 69f7f0f5890..355792858a9 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionPoolSPIComparator.java +++ b/src/main/java/org/olat/modules/qpool/QuestionPoolSPIComparator.java @@ -27,10 +27,10 @@ import java.util.Comparator; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class QuestionPoolSPIComparator implements Comparator<QuestionPoolSPI> { +public class QuestionPoolSPIComparator implements Comparator<QPoolSPI> { @Override - public int compare(QuestionPoolSPI o1, QuestionPoolSPI o2) { + public int compare(QPoolSPI o1, QPoolSPI o2) { int p1 = o1.getPriority(); int p2 = o2.getPriority(); return p1 < p2 ? 1 : (p1==p2 ? 0 : -1); diff --git a/src/main/java/org/olat/modules/qpool/QuestionPoolService.java b/src/main/java/org/olat/modules/qpool/QuestionPoolService.java index 6aa9cd1e135..79a9576c83b 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionPoolService.java +++ b/src/main/java/org/olat/modules/qpool/QuestionPoolService.java @@ -41,24 +41,40 @@ public interface QuestionPoolService { public String getTaxonomicPath(QuestionItem item); - public void deleteItems(List<QuestionItem> items); + public void deleteItems(List<QuestionItemShort> items); public List<Identity> getAuthors(QuestionItem item); - public void addAuthors(List<Identity> authors, List<QuestionItem> items); + public void addAuthors(List<Identity> authors, List<QuestionItemShort> items); - public QuestionItem importItem(Identity owner, String filename, File file); + public List<QuestionItem> importItems(Identity owner, String filename, File file); public VFSLeaf getRootFile(QuestionItem item); public VFSContainer getRootDirectory(QuestionItem item); + /** + * Create a new item and persist it on the database + * @param owner + * @param subject + * @param format + * @param language + * @param taxonLevel + * @param dir + * @param rootFilename + * @param type + * @return + */ + public QuestionItem createAndPersistItem(Identity owner, String subject, String format, String language, TaxonomyLevel taxonLevel, String dir, String rootFilename, QuestionType type); + + public QuestionItem loadItemById(Long key); + public QuestionItem updateItem(QuestionItem item); public int countItems(Identity author); - public ResultInfos<QuestionItem> getItems(Identity author, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); + public ResultInfos<QuestionItemShort> getItems(Identity author, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); public List<QuestionItem> getAllItems(int firstResult, int maxResults); @@ -69,37 +85,37 @@ public interface QuestionPoolService { public int getNumOfItemsInPool(Pool pool); - public ResultInfos<QuestionItem> getItemsOfPool(Pool pool, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); + public ResultInfos<QuestionItemShort> getItemsOfPool(Pool pool, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); - public void addItemToPool(QuestionItem item, Pool pool); + public void addItemToPool(QuestionItemShort item, Pool pool); //favorit public int getNumOfFavoritItems(Identity identity); - public ResultInfos<QuestionItem> getFavoritItems(Identity identity, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); + public ResultInfos<QuestionItemShort> getFavoritItems(Identity identity, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); //share - public void shareItems(List<QuestionItem> items, List<BusinessGroup> groups); + public void shareItems(List<QuestionItemShort> items, List<BusinessGroup> groups); public List<BusinessGroup> getResourcesWithSharedItems(Identity identity); public int countSharedItemByResource(OLATResource resource); - public ResultInfos<QuestionItem> getSharedItemByResource(OLATResource resource, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); + public ResultInfos<QuestionItemShort> getSharedItemByResource(OLATResource resource, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); //list - public QuestionItemCollection createCollection(Identity owner, String collectionName, List<QuestionItem> initialItems); + public QuestionItemCollection createCollection(Identity owner, String collectionName, List<QuestionItemShort> initialItems); - public void addItemToCollection(QuestionItem item, QuestionItemCollection collection); + public void addItemToCollection(QuestionItemShort item, QuestionItemCollection collection); public List<QuestionItemCollection> getCollections(Identity owner); public int countItemsOfCollection(QuestionItemCollection collection); - public ResultInfos<QuestionItem> getItemsOfCollection(QuestionItemCollection collection, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); + public ResultInfos<QuestionItemShort> getItemsOfCollection(QuestionItemCollection collection, SearchQuestionItemParams params, int firstResult, int maxResults, SortKey... orderBy); //study field admin diff --git a/src/main/java/org/olat/modules/qpool/_spring/qpoolContext.xml b/src/main/java/org/olat/modules/qpool/_spring/qpoolContext.xml index 2087333f832..fb56c18410f 100644 --- a/src/main/java/org/olat/modules/qpool/_spring/qpoolContext.xml +++ b/src/main/java/org/olat/modules/qpool/_spring/qpoolContext.xml @@ -15,6 +15,13 @@ <constructor-arg index="1" ref="qpoolModule" /> </bean> </property> + <property name="questionPoolProviders"> + <list> + <ref bean="qtiPoolServiceProvider"/> + <ref bean="textPoolServiceProvider"/> + <ref bean="filePoolServiceProvider"/> + </list> + </property> </bean> <!-- default configuration --> diff --git a/src/main/java/org/olat/modules/qpool/impl/PdfQuestionPoolServiceProvider.java b/src/main/java/org/olat/modules/qpool/impl/FileQPoolServiceProvider.java similarity index 87% rename from src/main/java/org/olat/modules/qpool/impl/PdfQuestionPoolServiceProvider.java rename to src/main/java/org/olat/modules/qpool/impl/FileQPoolServiceProvider.java index 1d315ebe781..b6311b32153 100644 --- a/src/main/java/org/olat/modules/qpool/impl/PdfQuestionPoolServiceProvider.java +++ b/src/main/java/org/olat/modules/qpool/impl/FileQPoolServiceProvider.java @@ -26,8 +26,9 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.util.vfs.VFSLeaf; import org.olat.modules.qpool.QuestionItem; -import org.olat.modules.qpool.QuestionPoolSPI; +import org.olat.modules.qpool.manager.AbstractQPoolServiceProvider; import org.olat.modules.qpool.ui.FilePreviewController; +import org.springframework.stereotype.Service; /** * @@ -35,9 +36,10 @@ import org.olat.modules.qpool.ui.FilePreviewController; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class PdfQuestionPoolServiceProvider implements QuestionPoolSPI { +@Service("filePoolServiceProvider") +public class FileQPoolServiceProvider extends AbstractQPoolServiceProvider { - public static final String PDF_FORMAT = "pdf"; + public static final String FILE_FORMAT = "raw-file"; @Override public int getPriority() { @@ -46,7 +48,7 @@ public class PdfQuestionPoolServiceProvider implements QuestionPoolSPI { @Override public String getFormat() { - return PDF_FORMAT; + return FILE_FORMAT; } @Override diff --git a/src/main/java/org/olat/modules/qpool/impl/TextQuestionPoolServiceProvider.java b/src/main/java/org/olat/modules/qpool/impl/TextQPoolServiceProvider.java similarity index 90% rename from src/main/java/org/olat/modules/qpool/impl/TextQuestionPoolServiceProvider.java rename to src/main/java/org/olat/modules/qpool/impl/TextQPoolServiceProvider.java index 43b3fa82978..061439cf17e 100644 --- a/src/main/java/org/olat/modules/qpool/impl/TextQuestionPoolServiceProvider.java +++ b/src/main/java/org/olat/modules/qpool/impl/TextQPoolServiceProvider.java @@ -26,8 +26,9 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.util.vfs.VFSLeaf; import org.olat.modules.qpool.QuestionItem; -import org.olat.modules.qpool.QuestionPoolSPI; +import org.olat.modules.qpool.manager.AbstractQPoolServiceProvider; import org.olat.modules.qpool.ui.TextPreviewController; +import org.springframework.stereotype.Service; /** * @@ -35,7 +36,8 @@ import org.olat.modules.qpool.ui.TextPreviewController; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class TextQuestionPoolServiceProvider implements QuestionPoolSPI { +@Service("textPoolServiceProvider") +public class TextQPoolServiceProvider extends AbstractQPoolServiceProvider { public static final String TXT_FORMAT = "txt"; diff --git a/src/main/java/org/olat/modules/qpool/manager/AbstractQPoolServiceProvider.java b/src/main/java/org/olat/modules/qpool/manager/AbstractQPoolServiceProvider.java new file mode 100644 index 00000000000..35462a6c5dd --- /dev/null +++ b/src/main/java/org/olat/modules/qpool/manager/AbstractQPoolServiceProvider.java @@ -0,0 +1,84 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.qpool.manager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.olat.core.CoreSpringFactory; +import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSLeaf; +import org.olat.modules.qpool.QPoolSPI; +import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionPoolService; + +/** + * + * Initial date: 07.03.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public abstract class AbstractQPoolServiceProvider implements QPoolSPI { + + private static final OLog log = Tracing.createLoggerFor(AbstractQPoolServiceProvider.class); + + + @Override + public List<QuestionItem> importItems(Identity owner, String filename, File file) { + List<QuestionItem> items = new ArrayList<QuestionItem>(); + QuestionItem item = importItem(owner, filename, file); + if(item != null) { + items.add(item); + } + return items; + } + + public QuestionItem importItem(Identity owner, String filename, File file) { + String dir = FileStorage.generateDir(); + VFSContainer itemDir = FileStorage.getContainer(dir); + + VFSLeaf leaf = itemDir.createChildLeaf(filename); + OutputStream out = leaf.getOutputStream(false); + InputStream in = null; + try { + in = new FileInputStream(file); + IOUtils.copy(in, out); + } catch (FileNotFoundException e) { + log.error("", e); + } catch (IOException e) { + log.error("", e); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + } + return CoreSpringFactory.getImpl(QuestionPoolService.class) + .createAndPersistItem(owner, filename, getFormat(), "de", null, dir, filename, null); + } +} diff --git a/src/main/java/org/olat/modules/qpool/manager/CollectionDAO.java b/src/main/java/org/olat/modules/qpool/manager/CollectionDAO.java index a31028f555b..74ac0ee4832 100644 --- a/src/main/java/org/olat/modules/qpool/manager/CollectionDAO.java +++ b/src/main/java/org/olat/modules/qpool/manager/CollectionDAO.java @@ -29,10 +29,10 @@ import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; -import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItemCollection; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.model.CollectionToItem; -import org.olat.modules.qpool.model.QuestionItemCollectionImpl; +import org.olat.modules.qpool.model.ItemCollectionImpl; import org.olat.modules.qpool.model.QuestionItemImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -52,7 +52,7 @@ public class CollectionDAO { private QuestionItemDAO questionItemDao; public QuestionItemCollection createCollection(String name, Identity identity) { - QuestionItemCollectionImpl collection = new QuestionItemCollectionImpl(); + ItemCollectionImpl collection = new ItemCollectionImpl(); collection.setCreationDate(new Date()); collection.setLastModified(new Date()); collection.setName(name); @@ -74,8 +74,17 @@ public class CollectionDAO { return items.get(0); } - public void addItemToCollection(QuestionItem item, QuestionItemCollection collection) { - QuestionItemImpl lockedItem = questionItemDao.loadForUpdate(item.getKey()); + /** + * Add an item to a collection + * @param itemKey + * @param collection + * @return true if the item is in the collection after the call + */ + public boolean addItemToCollection(Long itemKey, QuestionItemCollection collection) { + QuestionItemImpl lockedItem = questionItemDao.loadForUpdate(itemKey); + if(lockedItem == null) { + return false; + } if(!isInCollection(collection, lockedItem)) { CollectionToItem coll2Item = new CollectionToItem(); coll2Item.setCreationDate(new Date()); @@ -84,6 +93,7 @@ public class CollectionDAO { dbInstance.getCurrentEntityManager().persist(coll2Item); } dbInstance.commit(); + return true; } protected boolean isInCollection(QuestionItemCollection collection, QuestionItemImpl item) { @@ -107,7 +117,7 @@ public class CollectionDAO { .getSingleResult().intValue(); } - public List<QuestionItem> getItemsOfCollection(QuestionItemCollection collection, List<Long> inKeys, + public List<QuestionItemShort> getItemsOfCollection(QuestionItemCollection collection, List<Long> inKeys, int firstResult, int maxResults, SortKey... orderBy) { StringBuilder sb = new StringBuilder(); sb.append("select item from qcollection2item coll2item ") @@ -119,8 +129,8 @@ public class CollectionDAO { } PersistenceHelper.appendGroupBy(sb, "coll2item.item", orderBy); - TypedQuery<QuestionItem> query = dbInstance.getCurrentEntityManager() - .createQuery(sb.toString(), QuestionItem.class) + TypedQuery<QuestionItemShort> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), QuestionItemShort.class) .setParameter("collectionKey", collection.getKey()); if(inKeys != null && !inKeys.isEmpty()) { query.setParameter("itemKeys", inKeys); @@ -154,9 +164,9 @@ public class CollectionDAO { .getResultList(); } - public int deleteItemFromCollections(List<QuestionItem> items) { + public int deleteItemFromCollections(List<QuestionItemShort> items) { List<Long> keys = new ArrayList<Long>(); - for(QuestionItem item:items) { + for(QuestionItemShort item:items) { keys.add(item.getKey()); } diff --git a/src/main/java/org/olat/modules/qpool/manager/FileStorage.java b/src/main/java/org/olat/modules/qpool/manager/FileStorage.java new file mode 100644 index 00000000000..ba610f7cbb0 --- /dev/null +++ b/src/main/java/org/olat/modules/qpool/manager/FileStorage.java @@ -0,0 +1,86 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.qpool.manager; + +import java.util.UUID; + +import org.olat.core.CoreSpringFactory; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSItem; +import org.olat.core.util.vfs.VFSLeaf; +import org.olat.modules.qpool.QuestionPoolModule; + +/** + * + * + * + * Initial date: 07.03.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class FileStorage { + + private static final OLog log = Tracing.createLoggerFor(FileStorage.class); + + public static String generateDir() { + String uuid = UUID.randomUUID().toString(); + return generateDir(uuid); + } + + public static String generateDir(String uuid) { + String cleanUuid = uuid.replace("-", ""); + String firstToken = cleanUuid.substring(0, 2); + String secondToken = cleanUuid.substring(2, 4); + String thirdToken = cleanUuid.substring(4, 6); + String forthToken = cleanUuid.substring(6, 8); + StringBuilder sb = new StringBuilder(); + sb.append(firstToken).append("/") + .append(secondToken).append("/") + .append(thirdToken).append("/") + .append(forthToken).append("/"); + return sb.toString(); + } + + public static VFSContainer getContainer(String dir) { + VFSContainer rootContainer = CoreSpringFactory.getImpl(QuestionPoolModule.class).getRootContainer(); + String[] tokens = dir.split("/"); + String firstToken = tokens[0]; + VFSContainer firstContainer = getNextDirectory(rootContainer, firstToken); + String secondToken = tokens[1]; + VFSContainer secondContainer = getNextDirectory(firstContainer, secondToken); + String thirdToken = tokens[2]; + VFSContainer thridContainer = getNextDirectory(secondContainer, thirdToken); + String forthToken = tokens[3]; + return getNextDirectory(thridContainer, forthToken); + } + + private static VFSContainer getNextDirectory(VFSContainer container, String token) { + VFSItem nextContainer = container.resolve(token); + if(nextContainer instanceof VFSContainer) { + return (VFSContainer)nextContainer; + } else if (nextContainer instanceof VFSLeaf) { + log.error(""); + return null; + } + return container.createChildContainer(token); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/modules/qpool/manager/NullPoolService.java b/src/main/java/org/olat/modules/qpool/manager/NullPoolService.java index 183f9ceebda..2b881764f0e 100644 --- a/src/main/java/org/olat/modules/qpool/manager/NullPoolService.java +++ b/src/main/java/org/olat/modules/qpool/manager/NullPoolService.java @@ -94,7 +94,7 @@ public class NullPoolService implements ApplicationListener<ContextRefreshedEven for(int i=0; i<200; i++) { long randomIndex = Math.round(Math.random() * (fields.size() - 1)); TaxonomyLevel field = fields.get((int)randomIndex); - QuestionItem item = questionItemDao.create(null, "NGC " + i, QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), field, null, randomType()); + QuestionItem item = questionItemDao.createAndPersist(null, "NGC " + i, QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), field, null, null, randomType()); poolDao.addItemToPool(item, pools.get(0)); } } diff --git a/src/main/java/org/olat/modules/qpool/manager/PoolDAO.java b/src/main/java/org/olat/modules/qpool/manager/PoolDAO.java index 3e31c0f604d..24f8aa3f41c 100644 --- a/src/main/java/org/olat/modules/qpool/manager/PoolDAO.java +++ b/src/main/java/org/olat/modules/qpool/manager/PoolDAO.java @@ -32,6 +32,7 @@ import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.commons.persistence.SortKey; import org.olat.modules.qpool.Pool; import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.model.PoolImpl; import org.olat.modules.qpool.model.PoolToItem; import org.springframework.beans.factory.annotation.Autowired; @@ -66,9 +67,9 @@ public class PoolDAO { return pool; } - public int deleteFromPools(List<QuestionItem> items) { + public int deleteFromPools(List<QuestionItemShort> items) { List<Long> keys = new ArrayList<Long>(); - for(QuestionItem item:items) { + for(QuestionItemShort item:items) { keys.add(item.getKey()); } @@ -131,7 +132,7 @@ public class PoolDAO { return query.getResultList(); } - public void addItemToPool(QuestionItem item, Pool pool) { + public void addItemToPool(QuestionItemShort item, Pool pool) { QuestionItem lockedItem = questionItemDao.loadForUpdate(item.getKey()); if(!isInPool(lockedItem, pool)) { PoolToItem p2i = new PoolToItem(); @@ -163,7 +164,7 @@ public class PoolDAO { .getSingleResult().intValue(); } - public List<QuestionItem> getItemsOfPool(Pool pool, List<Long> inKeys, int firstResult, int maxResults, SortKey... orderBy) { + public List<QuestionItemShort> getItemsOfPool(Pool pool, List<Long> inKeys, int firstResult, int maxResults, SortKey... orderBy) { StringBuilder sb = new StringBuilder(); sb.append("select item from qpool2item pool2item") .append(" inner join pool2item.item item ") @@ -175,8 +176,8 @@ public class PoolDAO { PersistenceHelper.appendGroupBy(sb, "pool2item.item", orderBy); - TypedQuery<QuestionItem> query = dbInstance.getCurrentEntityManager() - .createQuery(sb.toString(), QuestionItem.class) + TypedQuery<QuestionItemShort> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), QuestionItemShort.class) .setParameter("poolKey", pool.getKey()); if(inKeys != null && inKeys.size() > 0) { query.setParameter("inKeys", inKeys); diff --git a/src/main/java/org/olat/modules/qpool/manager/QuestionItemDAO.java b/src/main/java/org/olat/modules/qpool/manager/QuestionItemDAO.java index 0c2cd37aca4..5b8d857464a 100644 --- a/src/main/java/org/olat/modules/qpool/manager/QuestionItemDAO.java +++ b/src/main/java/org/olat/modules/qpool/manager/QuestionItemDAO.java @@ -37,6 +37,7 @@ import org.olat.core.commons.services.mark.impl.MarkImpl; import org.olat.core.id.Identity; import org.olat.group.BusinessGroup; import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionStatus; import org.olat.modules.qpool.QuestionType; import org.olat.modules.qpool.TaxonomyLevel; @@ -61,60 +62,59 @@ public class QuestionItemDAO { private BaseSecurity securityManager; - public QuestionItem create(Identity owner, String subject, String format, String language, - TaxonomyLevel field, String rootFilename, QuestionType type) { - - String uuid = UUID.randomUUID().toString(); - return create(owner, subject, format, language, field, uuid, rootFilename, type) ; - } - - public QuestionItem create(Identity owner, String subject, String format, String language, - TaxonomyLevel taxonLevel, String uuid, String rootFilename, QuestionType type) { + public QuestionItemImpl create(String subject, String format, String dir, String rootFilename) { QuestionItemImpl item = new QuestionItemImpl(); - + + String uuid = UUID.randomUUID().toString(); item.setIdentifier(uuid); item.setCreationDate(new Date()); item.setLastModified(new Date()); item.setTitle(subject); item.setStatus(QuestionStatus.draft.name()); item.setUsage(0); + item.setNumOfAnswerAlternatives(0); + item.setFormat(format); + if(dir == null) { + item.setDirectory(FileStorage.generateDir(uuid)); + } else { + item.setDirectory(dir); + } + item.setRootFilename(rootFilename); + return item; + } + + public QuestionItemImpl createAndPersist(Identity owner, String subject, String format, String language, + TaxonomyLevel taxonLevel, String dir, String rootFilename, QuestionType type) { + QuestionItemImpl item = create(subject, format, dir, rootFilename); if(type != null) { item.setType(type.name()); } - item.setFormat(format); item.setLanguage(language); item.setTaxonomyLevel(taxonLevel); - item.setDirectory(generateDir(uuid)); - item.setRootFilename(rootFilename); - SecurityGroup ownerGroup = securityManager.createAndPersistSecurityGroup(); - item.setOwnerGroup(ownerGroup); - dbInstance.getCurrentEntityManager().persist(item); - if(owner != null) { - securityManager.addIdentityToSecurityGroup(owner, ownerGroup); - } + persist(owner, item); return item; } - public String generateDir(String uuid) { - String cleanUuid = uuid.replace("-", ""); - String firstToken = cleanUuid.substring(0, 2); - String secondToken = cleanUuid.substring(2, 4); - String thirdToken = cleanUuid.substring(4, 6); - String forthToken = cleanUuid.substring(6, 8); - StringBuilder sb = new StringBuilder(); - sb.append(firstToken).append("/") - .append(secondToken).append("/") - .append(thirdToken).append("/") - .append(forthToken).append("/"); - return sb.toString(); + public void persist(Identity owner, QuestionItemImpl item) { + if(item.getOwnerGroup() == null) { + SecurityGroup ownerGroup = securityManager.createAndPersistSecurityGroup(); + item.setOwnerGroup(ownerGroup); + } + dbInstance.getCurrentEntityManager().persist(item); + if(owner != null) { + securityManager.addIdentityToSecurityGroup(owner, item.getOwnerGroup()); + } } - + public QuestionItem merge(QuestionItem item) { + if(item instanceof QuestionItemImpl) { + ((QuestionItemImpl)item).setLastModified(new Date()); + } return dbInstance.getCurrentEntityManager().merge(item); } - public void addAuthors(List<Identity> authors, QuestionItem item) { - QuestionItemImpl lockedItem = loadForUpdate(item.getKey()); + public void addAuthors(List<Identity> authors, Long itemKey) { + QuestionItemImpl lockedItem = loadForUpdate(itemKey); SecurityGroup secGroup = lockedItem.getOwnerGroup(); for(Identity author:authors) { if(!securityManager.isIdentityInSecurityGroup(author, secGroup)) { @@ -138,7 +138,7 @@ public class QuestionItemDAO { .getSingleResult().intValue(); } - public List<QuestionItem> getItems(Identity me, List<Long> inKeys, int firstResult, int maxResults, SortKey... orderBy) { + public List<QuestionItemShort> getItems(Identity me, List<Long> inKeys, int firstResult, int maxResults, SortKey... orderBy) { StringBuilder sb = new StringBuilder(); sb.append("select item from questionitem item") .append(" inner join item.ownerGroup ownerGroup ") @@ -151,8 +151,8 @@ public class QuestionItemDAO { sb.append(" and item.key in (:itemKeys)"); } - TypedQuery<QuestionItem> query = dbInstance.getCurrentEntityManager() - .createQuery(sb.toString(), QuestionItem.class) + TypedQuery<QuestionItemShort> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), QuestionItemShort.class) .setParameter("identityKey", me.getKey()); if(inKeys != null && !inKeys.isEmpty()) { query.setParameter("itemKeys", inKeys); @@ -181,9 +181,9 @@ public class QuestionItemDAO { return query.getResultList(); } - public void delete(List<QuestionItem> items) { + public void delete(List<QuestionItemShort> items) { EntityManager em = dbInstance.getCurrentEntityManager(); - for(QuestionItem item:items) { + for(QuestionItemShort item:items) { QuestionItem refItem = em.getReference(QuestionItemImpl.class, item.getKey()); em.remove(refItem); } @@ -245,7 +245,7 @@ public class QuestionItemDAO { return query.getResultList(); } - public List<QuestionItem> getFavoritItems(Identity identity, List<Long> inKeys, int firstResult, int maxResults) { + public List<QuestionItemShort> getFavoritItems(Identity identity, List<Long> inKeys, int firstResult, int maxResults) { StringBuilder sb = new StringBuilder(); sb.append("select item from questionitem item") .append(" left join fetch item.taxonomyLevel taxonomyLevel") @@ -256,8 +256,8 @@ public class QuestionItemDAO { sb.append(" and item.key in (:itemKeys)"); } - TypedQuery<QuestionItem> query = dbInstance.getCurrentEntityManager() - .createQuery(sb.toString(), QuestionItem.class) + TypedQuery<QuestionItemShort> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), QuestionItemShort.class) .setParameter("identityKey", identity.getKey()); if(inKeys != null && !inKeys.isEmpty()) { query.setParameter("itemKeys", inKeys); @@ -284,11 +284,11 @@ public class QuestionItemDAO { dbInstance.commit();//release the lock asap } - public void share(QuestionItem item, List<OLATResource> resources) { + public void share(Long itemKey, List<OLATResource> resources) { EntityManager em = dbInstance.getCurrentEntityManager(); - QuestionItem lockedItem = loadForUpdate(item.getKey()); + QuestionItem lockedItem = loadForUpdate(itemKey); for(OLATResource resource:resources) { - if(!isShared(item, resource)) { + if(!isShared(lockedItem, resource)) { ResourceShareImpl share = new ResourceShareImpl(); share.setCreationDate(new Date()); share.setItem(lockedItem); @@ -324,7 +324,7 @@ public class QuestionItemDAO { return count.intValue(); } - public List<QuestionItem> getSharedItemByResource(OLATResource resource, List<Long> inKeys, + public List<QuestionItemShort> getSharedItemByResource(OLATResource resource, List<Long> inKeys, int firstResult, int maxResults, SortKey... orderBy) { StringBuilder sb = new StringBuilder(); sb.append("select item from qshareitem share") @@ -335,8 +335,8 @@ public class QuestionItemDAO { sb.append(" and item.key in (:itemKeys)"); } - TypedQuery<QuestionItem> query = dbInstance.getCurrentEntityManager() - .createQuery(sb.toString(), QuestionItem.class) + TypedQuery<QuestionItemShort> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), QuestionItemShort.class) .setParameter("resourceKey", resource.getKey()); if(inKeys != null && !inKeys.isEmpty()) { query.setParameter("itemKeys", inKeys); @@ -382,9 +382,9 @@ public class QuestionItemDAO { return query.getResultList(); } - public int deleteFromShares(List<QuestionItem> items) { + public int deleteFromShares(List<QuestionItemShort> items) { List<Long> keys = new ArrayList<Long>(); - for(QuestionItem item:items) { + for(QuestionItemShort item:items) { keys.add(item.getKey()); } StringBuilder sb = new StringBuilder(); diff --git a/src/main/java/org/olat/modules/qpool/manager/QuestionItemDocumentFactory.java b/src/main/java/org/olat/modules/qpool/manager/QuestionItemDocumentFactory.java index bae6945db6a..8f8f29d877d 100644 --- a/src/main/java/org/olat/modules/qpool/manager/QuestionItemDocumentFactory.java +++ b/src/main/java/org/olat/modules/qpool/manager/QuestionItemDocumentFactory.java @@ -34,7 +34,7 @@ import org.olat.core.util.StringHelper; import org.olat.modules.qpool.Pool; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; -import org.olat.modules.qpool.model.QuestionItemDocument; +import org.olat.modules.qpool.model.QItemDocument; import org.olat.resource.OLATResource; import org.olat.search.model.OlatDocument; import org.olat.search.service.SearchResourceContext; @@ -68,15 +68,14 @@ public class QuestionItemDocumentFactory { return null; } - public Document createDocument(SearchResourceContext searchResourceContext, QuestionItem item) { - + public Document createDocument(SearchResourceContext searchResourceContext, QuestionItem item) { OlatDocument oDocument = new OlatDocument(); oDocument.setId(item.getKey()); oDocument.setCreatedDate(item.getCreationDate()); oDocument.setTitle(item.getTitle()); oDocument.setDescription(item.getDescription()); oDocument.setResourceUrl("[QuestionItem:" + item.getKey() + "]"); - oDocument.setDocumentType(QuestionItemDocument.TYPE); + oDocument.setDocumentType(QItemDocument.TYPE); oDocument.setCssIcon("o_qitem_icon"); oDocument.setParentContextType(searchResourceContext.getParentContextType()); oDocument.setParentContextName(searchResourceContext.getParentContextName()); @@ -92,23 +91,28 @@ public class QuestionItemDocumentFactory { .append(" "); } oDocument.setAuthor(authorSb.toString()); + + //specific fields + + + //save owners key Document document = oDocument.getLuceneDocument(); for(Identity owner:owners) { - document.add(new StringField(QuestionItemDocument.OWNER_FIELD, owner.getKey().toString(), Field.Store.NO)); + document.add(new StringField(QItemDocument.OWNER_FIELD, owner.getKey().toString(), Field.Store.NO)); } //link resources List<OLATResource> resources = questionItemDao.getSharedResources(item); for(OLATResource resource:resources) { - document.add(new StringField(QuestionItemDocument.SHARE_FIELD, resource.getKey().toString(), Field.Store.NO)); + document.add(new StringField(QItemDocument.SHARE_FIELD, resource.getKey().toString(), Field.Store.NO)); } //need pools List<Pool> pools = poolDao.getPools(item); for(Pool pool:pools) { - document.add(new StringField(QuestionItemDocument.POOL_FIELD, pool.getKey().toString(), Field.Store.NO)); + document.add(new StringField(QItemDocument.POOL_FIELD, pool.getKey().toString(), Field.Store.NO)); } //need path @@ -116,7 +120,7 @@ public class QuestionItemDocumentFactory { if(StringHelper.containsNonWhitespace(path)) { for(StringTokenizer tokenizer = new StringTokenizer(path, "/"); tokenizer.hasMoreTokens(); ) { String nextToken = tokenizer.nextToken(); - document.add(new TextField(QuestionItemDocument.STUDY_FIELD, nextToken, Field.Store.NO)); + document.add(new TextField(QItemDocument.STUDY_FIELD, nextToken, Field.Store.NO)); } } return document; diff --git a/src/main/java/org/olat/modules/qpool/manager/QuestionPoolServiceImpl.java b/src/main/java/org/olat/modules/qpool/manager/QuestionPoolServiceImpl.java index 3ecfec1a0a0..a0c54402ff1 100644 --- a/src/main/java/org/olat/modules/qpool/manager/QuestionPoolServiceImpl.java +++ b/src/main/java/org/olat/modules/qpool/manager/QuestionPoolServiceImpl.java @@ -20,16 +20,9 @@ package org.olat.modules.qpool.manager; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -import java.util.UUID; -import org.apache.commons.io.IOUtils; import org.olat.basesecurity.BaseSecurity; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DefaultResultInfos; @@ -39,20 +32,21 @@ import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; -import org.olat.core.util.ZipUtil; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.group.BusinessGroup; import org.olat.modules.qpool.Pool; +import org.olat.modules.qpool.QPoolSPI; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItemCollection; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolModule; -import org.olat.modules.qpool.QuestionPoolSPI; import org.olat.modules.qpool.QuestionPoolService; +import org.olat.modules.qpool.QuestionType; import org.olat.modules.qpool.TaxonomyLevel; import org.olat.modules.qpool.model.PoolImpl; -import org.olat.modules.qpool.model.QuestionItemDocument; +import org.olat.modules.qpool.model.QItemDocument; import org.olat.modules.qpool.model.QuestionItemImpl; import org.olat.modules.qpool.model.SearchQuestionItemParams; import org.olat.resource.OLATResource; @@ -103,7 +97,7 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } @Override - public void deleteItems(List<QuestionItem> items) { + public void deleteItems(List<QuestionItemShort> items) { if(items == null || items.isEmpty()) { return; //nothing to do } @@ -116,13 +110,13 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } @Override - public void addAuthors(List<Identity> authors, List<QuestionItem> items) { + public void addAuthors(List<Identity> authors, List<QuestionItemShort> items) { if(authors == null || authors.isEmpty() || items == null || items.isEmpty()) { return;//nothing to do } - for(QuestionItem item:items) { - questionItemDao.addAuthors(authors, item); + for(QuestionItemShort item:items) { + questionItemDao.addAuthors(authors, item.getKey()); } } @@ -137,24 +131,25 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { return securityManager.getIdentitiesOfSecurityGroup(itemImpl.getOwnerGroup()); } - public QuestionItem getItem() { - return null; + @Override + public QuestionItem loadItemById(Long key) { + return questionItemDao.loadById(key); } - + public QuestionItem updateItem(QuestionItem item) { QuestionItem mergedItem = questionItemDao.merge(item); dbInstance.commit();// - lifeIndexer.indexDocument(QuestionItemDocument.TYPE, mergedItem.getKey()); + lifeIndexer.indexDocument(QItemDocument.TYPE, mergedItem.getKey()); return mergedItem; } @Override - public QuestionItem importItem(Identity owner, String filename, File file) { - QuestionItem importedItem = null; - List<QuestionPoolSPI> providers = qpoolModule.getQuestionPoolProviders(); - for(QuestionPoolSPI provider:providers) { + public List<QuestionItem> importItems(Identity owner, String filename, File file) { + List<QuestionItem> importedItem = null; + List<QPoolSPI> providers = qpoolModule.getQuestionPoolProviders(); + for(QPoolSPI provider:providers) { if(provider.isCompatible(filename, file)) { - importedItem = importItem(owner, filename, file, provider); + importedItem = provider.importItems(owner, filename, file); } } return importedItem; @@ -186,10 +181,16 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { return null; } - private QuestionItem importItem(Identity owner, String filename, File file, QuestionPoolSPI provider) { + @Override + public QuestionItem createAndPersistItem(Identity owner, String subject, String format, String language, + TaxonomyLevel taxonLevel, String dir, String rootFilename, QuestionType type) { + return questionItemDao.createAndPersist(owner, subject, format, language, taxonLevel, dir, rootFilename, type); + } + + /*private QuestionItem importItem(Identity owner, String filename, File file, QPoolSPI provider) { String uuid = UUID.randomUUID().toString(); VFSContainer root = qpoolModule.getRootContainer(); - VFSContainer itemDir = getDirectory(root, uuid); + VFSContainer itemDir = FileStorage.getDirectory(root, uuid); String rootFilename = filename; if(filename.toLowerCase().endsWith(".zip")) { @@ -216,7 +217,7 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { return questionItemDao.create(owner, filename, provider.getFormat(), "de", null, uuid, rootFilename, null); } - private String searchRootFilename(String path, VFSContainer dir, QuestionPoolSPI provider) { + private String searchRootFilename(String path, VFSContainer dir, QPoolSPI provider) { for(VFSItem item:dir.getItems()) { if(item instanceof VFSContainer) { String root = searchRootFilename(path + "/" + item.getName(), (VFSContainer)item, provider); @@ -230,30 +231,9 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } } return null; - } - - private VFSContainer getDirectory(VFSContainer rootContainer, String uuid) { - String cleanUuid = uuid.replace("-", ""); - String firstToken = cleanUuid.substring(0, 2); - VFSContainer firstContainer = getNextDirectory(rootContainer, firstToken); - String secondToken = cleanUuid.substring(2, 4); - VFSContainer secondContainer = getNextDirectory(firstContainer, secondToken); - String thirdToken = cleanUuid.substring(4, 6); - VFSContainer thridContainer = getNextDirectory(secondContainer, thirdToken); - String forthToken = cleanUuid.substring(6, 8); - return getNextDirectory(thridContainer, forthToken); - } + }*/ - private VFSContainer getNextDirectory(VFSContainer container, String token) { - VFSItem nextContainer = container.resolve(token); - if(nextContainer instanceof VFSContainer) { - return (VFSContainer)nextContainer; - } else if (nextContainer instanceof VFSLeaf) { - log.error(""); - return null; - } - return container.createChildContainer(token); - } + @Override public int countItems(Identity author) { @@ -261,30 +241,30 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } @Override - public ResultInfos<QuestionItem> getItems(Identity author, SearchQuestionItemParams searchParams, int firstResult, int maxResults, SortKey... orderBy) { + public ResultInfos<QuestionItemShort> getItems(Identity author, SearchQuestionItemParams searchParams, int firstResult, int maxResults, SortKey... orderBy) { if(searchParams != null && StringHelper.containsNonWhitespace(searchParams.getSearchString())) { try { String queryString = searchParams.getSearchString(); List<String> condQueries = new ArrayList<String>(); - condQueries.add(QuestionItemDocument.OWNER_FIELD + ":" + author.getKey()); + condQueries.add(QItemDocument.OWNER_FIELD + ":" + author.getKey()); List<Long> results = searchClient.doSearch(queryString, condQueries, searchParams.getIdentity(), searchParams.getRoles(), firstResult, 10000, orderBy); int initialResultsSize = results.size(); if(results.isEmpty()) { - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } else if(results.size() > maxResults) { results = results.subList(0, Math.min(results.size(), maxResults * 2)); } - List<QuestionItem> items = questionItemDao.getItems(author, results, firstResult, maxResults, orderBy); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), firstResult + initialResultsSize, items); + List<QuestionItemShort> items = questionItemDao.getItems(author, results, firstResult, maxResults, orderBy); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), firstResult + initialResultsSize, items); } catch (Exception e) { log.error("", e); } - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } else { - List<QuestionItem> items = questionItemDao.getItems(author, null, firstResult, maxResults, orderBy); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), -1, items); + List<QuestionItemShort> items = questionItemDao.getItems(author, null, firstResult, maxResults, orderBy); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), -1, items); } } @@ -304,7 +284,7 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } @Override - public ResultInfos<QuestionItem> getItemsOfPool(Pool pool, SearchQuestionItemParams searchParams, + public ResultInfos<QuestionItemShort> getItemsOfPool(Pool pool, SearchQuestionItemParams searchParams, int firstResult, int maxResults, SortKey... orderBy) { if(searchParams != null && StringHelper.containsNonWhitespace(searchParams.getSearchString())) { @@ -317,24 +297,24 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { int initialResultsSize = results.size(); if(results.isEmpty()) { - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } else if(results.size() > maxResults) { results = results.subList(0, Math.min(results.size(), maxResults * 2)); } - List<QuestionItem> items = poolDao.getItemsOfPool(pool, results, 0, maxResults, orderBy); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), firstResult + initialResultsSize, items); + List<QuestionItemShort> items = poolDao.getItemsOfPool(pool, results, 0, maxResults, orderBy); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), firstResult + initialResultsSize, items); } catch (Exception e) { log.error("", e); } - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } else { - List<QuestionItem> items = poolDao.getItemsOfPool(pool, null, firstResult, maxResults, orderBy); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), -1, items); + List<QuestionItemShort> items = poolDao.getItemsOfPool(pool, null, firstResult, maxResults, orderBy); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), -1, items); } } @Override - public void addItemToPool(QuestionItem item, Pool pool) { + public void addItemToPool(QuestionItemShort item, Pool pool) { poolDao.addItemToPool(item, pool); } @@ -344,7 +324,7 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } @Override - public ResultInfos<QuestionItem> getFavoritItems(Identity identity, SearchQuestionItemParams searchParams, + public ResultInfos<QuestionItemShort> getFavoritItems(Identity identity, SearchQuestionItemParams searchParams, int firstResult, int maxResults, SortKey... orderBy) { if(searchParams != null && StringHelper.containsNonWhitespace(searchParams.getSearchString())) { @@ -359,17 +339,17 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { searchParams.getIdentity(), searchParams.getRoles(), firstResult, maxResults * 5, orderBy); if(results.isEmpty()) { - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } - List<QuestionItem> items = questionItemDao.getFavoritItems(identity, results, firstResult, maxResults); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), firstResult + results.size(), items); + List<QuestionItemShort> items = questionItemDao.getFavoritItems(identity, results, firstResult, maxResults); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), firstResult + results.size(), items); } catch (Exception e) { log.error("", e); } - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } else { - List<QuestionItem> items = questionItemDao.getFavoritItems(identity, null, firstResult, maxResults); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), -1, items); + List<QuestionItemShort> items = questionItemDao.getFavoritItems(identity, null, firstResult, maxResults); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), -1, items); } } @@ -384,7 +364,7 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } @Override - public void shareItems(List<QuestionItem> items, List<BusinessGroup> groups) { + public void shareItems(List<QuestionItemShort> items, List<BusinessGroup> groups) { if(items == null || items.isEmpty() || groups == null || groups.isEmpty()) { return;//nothing to do } @@ -394,8 +374,8 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { resources.add(group.getResource()); } - for(QuestionItem item:items) { - questionItemDao.share(item, resources); + for(QuestionItemShort item:items) { + questionItemDao.share(item.getKey(), resources); } } @@ -410,47 +390,47 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } @Override - public ResultInfos<QuestionItem> getSharedItemByResource(OLATResource resource, SearchQuestionItemParams searchParams, + public ResultInfos<QuestionItemShort> getSharedItemByResource(OLATResource resource, SearchQuestionItemParams searchParams, int firstResult, int maxResults, SortKey... orderBy) { if(searchParams != null && StringHelper.containsNonWhitespace(searchParams.getSearchString())) { try { String queryString = searchParams.getSearchString(); List<String> condQueries = new ArrayList<String>(); - condQueries.add(QuestionItemDocument.SHARE_FIELD + ":" + resource.getKey()); + condQueries.add(QItemDocument.SHARE_FIELD + ":" + resource.getKey()); List<Long> results = searchClient.doSearch(queryString, condQueries, searchParams.getIdentity(), searchParams.getRoles(), firstResult, maxResults * 5, orderBy); int initialResultsSize = results.size(); if(results.isEmpty()) { - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } else if(results.size() > maxResults) { results = results.subList(0, Math.min(results.size(), maxResults * 2)); } - List<QuestionItem> items = questionItemDao.getSharedItemByResource(resource, results, firstResult, maxResults); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), firstResult + initialResultsSize, items); + List<QuestionItemShort> items = questionItemDao.getSharedItemByResource(resource, results, firstResult, maxResults); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), firstResult + initialResultsSize, items); } catch (Exception e) { log.error("", e); } - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } else { - List<QuestionItem> items = questionItemDao.getSharedItemByResource(resource, null, firstResult, maxResults, orderBy); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), -1, items); + List<QuestionItemShort> items = questionItemDao.getSharedItemByResource(resource, null, firstResult, maxResults, orderBy); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), -1, items); } } @Override - public QuestionItemCollection createCollection(Identity owner, String collectionName, List<QuestionItem> initialItems) { + public QuestionItemCollection createCollection(Identity owner, String collectionName, List<QuestionItemShort> initialItems) { QuestionItemCollection coll = collectionDao.createCollection(collectionName, owner); - for(QuestionItem item:initialItems) { - collectionDao.addItemToCollection(item, coll); + for(QuestionItemShort item:initialItems) { + collectionDao.addItemToCollection(item.getKey(), coll); } return coll; } @Override - public void addItemToCollection(QuestionItem item, QuestionItemCollection coll) { - collectionDao.addItemToCollection(item, coll); + public void addItemToCollection(QuestionItemShort item, QuestionItemCollection coll) { + collectionDao.addItemToCollection(item.getKey(), coll); } @Override @@ -464,7 +444,7 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { } @Override - public ResultInfos<QuestionItem> getItemsOfCollection(QuestionItemCollection collection, SearchQuestionItemParams searchParams, + public ResultInfos<QuestionItemShort> getItemsOfCollection(QuestionItemCollection collection, SearchQuestionItemParams searchParams, int firstResult, int maxResults, SortKey... orderBy) { if(searchParams != null && StringHelper.containsNonWhitespace(searchParams.getSearchString())) { @@ -478,17 +458,17 @@ public class QuestionPoolServiceImpl implements QuestionPoolService { firstResult, maxResults * 5, orderBy); if(results.isEmpty()) { - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } - List<QuestionItem> items = collectionDao.getItemsOfCollection(collection, results, firstResult, maxResults, orderBy); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), firstResult + results.size(), items); + List<QuestionItemShort> items = collectionDao.getItemsOfCollection(collection, results, firstResult, maxResults, orderBy); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), firstResult + results.size(), items); } catch (Exception e) { log.error("", e); } - return new DefaultResultInfos<QuestionItem>(); + return new DefaultResultInfos<QuestionItemShort>(); } else { - List<QuestionItem> items = collectionDao.getItemsOfCollection(collection, null, firstResult, maxResults, orderBy); - return new DefaultResultInfos<QuestionItem>(firstResult + items.size(), -1, items); + List<QuestionItemShort> items = collectionDao.getItemsOfCollection(collection, null, firstResult, maxResults, orderBy); + return new DefaultResultInfos<QuestionItemShort>(firstResult + items.size(), -1, items); } } diff --git a/src/main/java/org/olat/modules/qpool/model/CollectionToItem.java b/src/main/java/org/olat/modules/qpool/model/CollectionToItem.java index 065069028c9..c585987fe66 100644 --- a/src/main/java/org/olat/modules/qpool/model/CollectionToItem.java +++ b/src/main/java/org/olat/modules/qpool/model/CollectionToItem.java @@ -59,7 +59,7 @@ public class CollectionToItem implements CreateInfo, Persistable { @Column(name="creationdate", nullable=false, insertable=true, updatable=false) private Date creationDate; - @ManyToOne(targetEntity=QuestionItemCollectionImpl.class,fetch=FetchType.LAZY,optional=false) + @ManyToOne(targetEntity=ItemCollectionImpl.class,fetch=FetchType.LAZY,optional=false) @JoinColumn(name="fk_collection_id", nullable=false, updatable=false) private QuestionItemCollection collection; diff --git a/src/main/java/org/olat/modules/qpool/model/QuestionItemCollectionImpl.java b/src/main/java/org/olat/modules/qpool/model/ItemCollectionImpl.java similarity index 94% rename from src/main/java/org/olat/modules/qpool/model/QuestionItemCollectionImpl.java rename to src/main/java/org/olat/modules/qpool/model/ItemCollectionImpl.java index c40e68b119e..1f441601882 100644 --- a/src/main/java/org/olat/modules/qpool/model/QuestionItemCollectionImpl.java +++ b/src/main/java/org/olat/modules/qpool/model/ItemCollectionImpl.java @@ -46,7 +46,7 @@ import org.olat.modules.qpool.QuestionItemCollection; */ @Entity(name="qcollection") @Table(name="o_qp_item_collection") -public class QuestionItemCollectionImpl implements QuestionItemCollection, Persistable { +public class ItemCollectionImpl implements QuestionItemCollection, Persistable { private static final long serialVersionUID = 898627243085538859L; @@ -124,8 +124,8 @@ public class QuestionItemCollectionImpl implements QuestionItemCollection, Persi if(this == obj) { return true; } - if(obj instanceof QuestionItemCollectionImpl) { - QuestionItemCollectionImpl coll = (QuestionItemCollectionImpl)obj; + if(obj instanceof ItemCollectionImpl) { + ItemCollectionImpl coll = (ItemCollectionImpl)obj; return key != null && key.equals(coll.key); } return false; diff --git a/src/main/java/org/olat/modules/qpool/model/QuestionItemDocument.java b/src/main/java/org/olat/modules/qpool/model/QItemDocument.java similarity index 91% rename from src/main/java/org/olat/modules/qpool/model/QuestionItemDocument.java rename to src/main/java/org/olat/modules/qpool/model/QItemDocument.java index 3112479ebad..66246a0e7a5 100644 --- a/src/main/java/org/olat/modules/qpool/model/QuestionItemDocument.java +++ b/src/main/java/org/olat/modules/qpool/model/QItemDocument.java @@ -27,10 +27,10 @@ import org.olat.search.model.OlatDocument; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class QuestionItemDocument extends OlatDocument { +public class QItemDocument extends OlatDocument { private static final long serialVersionUID = 2137366338712446727L; - public static final String TYPE = "type.question.item"; + public static final String TYPE = "type.qp.item"; public static final String OWNER_FIELD = "owner"; public static final String SHARE_FIELD = "share"; diff --git a/src/main/java/org/olat/modules/qpool/ui/ImportQuestionItemController.java b/src/main/java/org/olat/modules/qpool/ui/ImportController.java similarity index 92% rename from src/main/java/org/olat/modules/qpool/ui/ImportQuestionItemController.java rename to src/main/java/org/olat/modules/qpool/ui/ImportController.java index 1e305b301a1..49c93a93a1f 100644 --- a/src/main/java/org/olat/modules/qpool/ui/ImportQuestionItemController.java +++ b/src/main/java/org/olat/modules/qpool/ui/ImportController.java @@ -38,12 +38,12 @@ import org.olat.modules.qpool.QuestionPoolService; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class ImportQuestionItemController extends FormBasicController { +public class ImportController extends FormBasicController { private FileElement fileEl; private final QuestionPoolService qpoolservice; - public ImportQuestionItemController(UserRequest ureq, WindowControl wControl) { + public ImportController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); qpoolservice = CoreSpringFactory.getImpl(QuestionPoolService.class); initForm(ureq); @@ -73,7 +73,7 @@ public class ImportQuestionItemController extends FormBasicController { protected void formOK(UserRequest ureq) { String filename = fileEl.getUploadFileName(); File file = fileEl.getUploadFile(); - qpoolservice.importItem(getIdentity(), filename, file); + qpoolservice.importItems(getIdentity(), filename, file); fireEvent(ureq, Event.DONE_EVENT); } diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionItemRow.java b/src/main/java/org/olat/modules/qpool/ui/ItemRow.java similarity index 92% rename from src/main/java/org/olat/modules/qpool/ui/QuestionItemRow.java rename to src/main/java/org/olat/modules/qpool/ui/ItemRow.java index e3b7b4c6d19..b03e43204ff 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionItemRow.java +++ b/src/main/java/org/olat/modules/qpool/ui/ItemRow.java @@ -23,7 +23,6 @@ import java.math.BigDecimal; import java.util.Date; import org.olat.core.gui.components.form.flexible.elements.FormLink; -import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionStatus; import org.olat.modules.qpool.QuestionType; @@ -33,13 +32,13 @@ import org.olat.modules.qpool.QuestionType; * Initial date: 23.01.2013<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class QuestionItemRow implements QuestionItemShort { +public class ItemRow implements QuestionItemShort { - private final QuestionItem delegate; + private final QuestionItemShort delegate; private FormLink markLink; - public QuestionItemRow(QuestionItem item) { + public ItemRow(QuestionItemShort item) { this.delegate = item; } @@ -78,10 +77,6 @@ public class QuestionItemRow implements QuestionItemShort { return delegate.getLanguage(); } - public String getTaxonomicPath() { - return delegate.getTaxonomicPath(); - } - public String getTaxonomyLevelName() { return delegate.getTaxonomyLevelName(); } @@ -136,15 +131,11 @@ public class QuestionItemRow implements QuestionItemShort { return delegate.getLastModified(); } - - @Override public String getFormat() { return delegate.getFormat(); } - - @Override public QuestionStatus getQuestionStatus() { return delegate.getQuestionStatus(); @@ -155,12 +146,10 @@ public class QuestionItemRow implements QuestionItemShort { return delegate.getQuestionType(); } - - - + /* public QuestionItem getItem() { return delegate; - } + }*/ public FormLink getMarkLink() { return markLink; diff --git a/src/main/java/org/olat/modules/qpool/ui/ItemRowsSource.java b/src/main/java/org/olat/modules/qpool/ui/ItemRowsSource.java index c9df55a8d31..5dbf4501764 100644 --- a/src/main/java/org/olat/modules/qpool/ui/ItemRowsSource.java +++ b/src/main/java/org/olat/modules/qpool/ui/ItemRowsSource.java @@ -34,5 +34,5 @@ public interface ItemRowsSource { public int getRowCount(); - public ResultInfos<QuestionItemRow> getRows(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy); + public ResultInfos<ItemRow> getRows(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy); } diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionItemMetadatasController.java b/src/main/java/org/olat/modules/qpool/ui/MetadatasController.java similarity index 98% rename from src/main/java/org/olat/modules/qpool/ui/QuestionItemMetadatasController.java rename to src/main/java/org/olat/modules/qpool/ui/MetadatasController.java index 6333cfe7b3b..e0682260140 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionItemMetadatasController.java +++ b/src/main/java/org/olat/modules/qpool/ui/MetadatasController.java @@ -47,7 +47,7 @@ import org.olat.modules.qpool.ui.edit.TechnicalMetadataEditController; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class QuestionItemMetadatasController extends BasicController { +public class MetadatasController extends BasicController { private final VelocityContainer mainVC; private final GeneralMetadataController generalCtrl; @@ -66,7 +66,7 @@ public class QuestionItemMetadatasController extends BasicController { private QuestionItem item; - public QuestionItemMetadatasController(UserRequest ureq, WindowControl wControl, QuestionItem item) { + public MetadatasController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl); this.item = item; diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionEvent.java b/src/main/java/org/olat/modules/qpool/ui/QItemEvent.java similarity index 83% rename from src/main/java/org/olat/modules/qpool/ui/QuestionEvent.java rename to src/main/java/org/olat/modules/qpool/ui/QItemEvent.java index f6917e09282..cff9f81c49c 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionEvent.java +++ b/src/main/java/org/olat/modules/qpool/ui/QItemEvent.java @@ -20,7 +20,7 @@ package org.olat.modules.qpool.ui; import org.olat.core.gui.control.Event; -import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; /** * @@ -28,17 +28,17 @@ import org.olat.modules.qpool.QuestionItem; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class QuestionEvent extends Event { +public class QItemEvent extends Event { private static final long serialVersionUID = 1868410260121125418L; - private final QuestionItem item; + private final QuestionItemShort item; - public QuestionEvent(String cmd, QuestionItem item) { + public QItemEvent(String cmd, QuestionItemShort item) { super(cmd); this.item = item; } - public QuestionItem getItem() { + public QuestionItemShort getItem() { return item; } } diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionItemDataModel.java b/src/main/java/org/olat/modules/qpool/ui/QuestionItemDataModel.java index 879d2ea97a5..186de0fad10 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionItemDataModel.java +++ b/src/main/java/org/olat/modules/qpool/ui/QuestionItemDataModel.java @@ -39,9 +39,9 @@ import org.olat.modules.qpool.QuestionType; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class QuestionItemDataModel implements FlexiTableDataModel, FlexiTableDataSource<QuestionItemRow>, TableDataModel<QuestionItemRow> { +public class QuestionItemDataModel implements FlexiTableDataModel, FlexiTableDataSource<ItemRow>, TableDataModel<ItemRow> { - private List<QuestionItemRow> rows; + private List<ItemRow> rows; private FlexiTableColumnModel columnModel; private ItemRowsSource source; private final Translator translator; @@ -75,25 +75,25 @@ public class QuestionItemDataModel implements FlexiTableDataModel, FlexiTableDat } @Override - public QuestionItemRow getObject(int row) { + public ItemRow getObject(int row) { return rows.get(row); } @Override - public void setObjects(List<QuestionItemRow> objects) { - rows = new ArrayList<QuestionItemRow>(objects); + public void setObjects(List<ItemRow> objects) { + rows = new ArrayList<ItemRow>(objects); } @Override - public ResultInfos<QuestionItemRow> load(int firstResult, int maxResults, SortKey... orderBy) { + public ResultInfos<ItemRow> load(int firstResult, int maxResults, SortKey... orderBy) { if(rows == null) { - rows = new ArrayList<QuestionItemRow>(); + rows = new ArrayList<ItemRow>(); } for(int i=rows.size(); i<firstResult; i++) { rows.add(null); } - ResultInfos<QuestionItemRow> newRows = source.getRows(null, null, firstResult, maxResults, orderBy); + ResultInfos<ItemRow> newRows = source.getRows(null, null, firstResult, maxResults, orderBy); if(firstResult == 0) { if(newRows.getObjects().size() < maxResults) { rowCount = newRows.getObjects().size(); @@ -110,20 +110,20 @@ public class QuestionItemDataModel implements FlexiTableDataModel, FlexiTableDat rows.add(newRows.getObjects().get(i)); } } - return new DefaultResultInfos<QuestionItemRow>(newRows.getNextFirstResult(), newRows.getCorrectedRowCount(), rows); + return new DefaultResultInfos<ItemRow>(newRows.getNextFirstResult(), newRows.getCorrectedRowCount(), rows); } @Override - public ResultInfos<QuestionItemRow> search(String query, List<String> condQueries, int firstResult, + public ResultInfos<ItemRow> search(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { if(firstResult == 0) { - rows = new ArrayList<QuestionItemRow>(); + rows = new ArrayList<ItemRow>(); } else { for(int i=rows.size(); i<firstResult; i++) { rows.add(null); } } - ResultInfos<QuestionItemRow> newRows = source.getRows(query, condQueries, firstResult, maxResults, orderBy); + ResultInfos<ItemRow> newRows = source.getRows(query, condQueries, firstResult, maxResults, orderBy); if(newRows.getCorrectedRowCount() >= 0) { rowCount = newRows.getCorrectedRowCount(); } else if(firstResult == 0) { @@ -138,7 +138,7 @@ public class QuestionItemDataModel implements FlexiTableDataModel, FlexiTableDat rows.add(newRows.getObjects().get(i)); } } - return new DefaultResultInfos<QuestionItemRow>(newRows.getNextFirstResult(), newRows.getCorrectedRowCount(), rows); + return new DefaultResultInfos<ItemRow>(newRows.getNextFirstResult(), newRows.getCorrectedRowCount(), rows); } @Override @@ -153,7 +153,7 @@ public class QuestionItemDataModel implements FlexiTableDataModel, FlexiTableDat @Override public Object getValueAt(int row, int col) { - QuestionItemRow item = getObject(row); + ItemRow item = getObject(row); switch(Cols.values()[col]) { case key: return item.getKey(); case identifier: return item.getIdentifier(); diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionItemDetailsController.java b/src/main/java/org/olat/modules/qpool/ui/QuestionItemDetailsController.java index 898eafd0230..940be7e074c 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionItemDetailsController.java +++ b/src/main/java/org/olat/modules/qpool/ui/QuestionItemDetailsController.java @@ -42,8 +42,9 @@ import org.olat.group.BusinessGroup; import org.olat.group.model.BusinessGroupSelectionEvent; import org.olat.group.ui.main.SelectBusinessGroupController; import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolModule; -import org.olat.modules.qpool.QuestionPoolSPI; +import org.olat.modules.qpool.QPoolSPI; import org.olat.modules.qpool.QuestionPoolService; /** @@ -61,7 +62,7 @@ public class QuestionItemDetailsController extends BasicController { private final VelocityContainer mainVC; private DialogBoxController confirmDeleteBox; private SelectBusinessGroupController selectGroupCtrl; - private final QuestionItemMetadatasController metadatasCtrl; + private final MetadatasController metadatasCtrl; private final UserCommentsAndRatingsController commentsAndRatingCtr; private final QuestionPoolModule poolModule; @@ -73,7 +74,7 @@ public class QuestionItemDetailsController extends BasicController { poolModule = CoreSpringFactory.getImpl(QuestionPoolModule.class); qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); - QuestionPoolSPI spi = poolModule.getQuestionPoolProvider(item.getFormat()); + QPoolSPI spi = poolModule.getQuestionPoolProvider(item.getFormat()); if(spi == null) { editCtrl = new QuestionItemRawController(ureq, wControl); } else { @@ -84,7 +85,7 @@ public class QuestionItemDetailsController extends BasicController { } listenTo(editCtrl); - metadatasCtrl = new QuestionItemMetadatasController(ureq, wControl, item); + metadatasCtrl = new MetadatasController(ureq, wControl, item); listenTo(metadatasCtrl); Roles roles = ureq.getUserSession().getRoles(); @@ -164,7 +165,7 @@ public class QuestionItemDetailsController extends BasicController { listenTo(cmc); } - private void doShareItems(UserRequest ureq, QuestionItem item, List<BusinessGroup> groups) { + private void doShareItems(UserRequest ureq, QuestionItemShort item, List<BusinessGroup> groups) { qpoolService.shareItems(Collections.singletonList(item), groups); fireEvent(ureq, new QPoolEvent(QPoolEvent.ITEM_SHARED)); } @@ -174,7 +175,7 @@ public class QuestionItemDetailsController extends BasicController { confirmDeleteBox.setUserObject(item); } - private void doDelete(UserRequest ureq, QuestionItem item) { + private void doDelete(UserRequest ureq, QuestionItemShort item) { qpoolService.deleteItems(Collections.singletonList(item)); fireEvent(ureq, new QPoolEvent(QPoolEvent.ITEM_DELETED)); showInfo("item.deleted"); diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionItemPreviewController.java b/src/main/java/org/olat/modules/qpool/ui/QuestionItemPreviewController.java index a3e1356aefe..c73b67f2146 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionItemPreviewController.java +++ b/src/main/java/org/olat/modules/qpool/ui/QuestionItemPreviewController.java @@ -30,7 +30,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolModule; -import org.olat.modules.qpool.QuestionPoolSPI; +import org.olat.modules.qpool.QPoolSPI; /** * @@ -74,7 +74,7 @@ public class QuestionItemPreviewController extends BasicController { removeAsListenerAndDispose(previewCtrl); Component content; - QuestionPoolSPI spi = poolModule.getQuestionPoolProvider(item.getFormat()); + QPoolSPI spi = poolModule.getQuestionPoolProvider(item.getFormat()); if(spi == null) { content = getRawContent(item); } else { diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionItemsSource.java b/src/main/java/org/olat/modules/qpool/ui/QuestionItemsSource.java index 7f658d42268..42ea18f393b 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionItemsSource.java +++ b/src/main/java/org/olat/modules/qpool/ui/QuestionItemsSource.java @@ -23,7 +23,7 @@ import java.util.List; import org.olat.core.commons.persistence.ResultInfos; import org.olat.core.commons.persistence.SortKey; -import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; /** * @@ -35,6 +35,6 @@ public interface QuestionItemsSource { public int getNumOfItems(); - public ResultInfos<QuestionItem> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy); + public ResultInfos<QuestionItemShort> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy); } diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionListController.java b/src/main/java/org/olat/modules/qpool/ui/QuestionListController.java index 3a9bd90b808..d4e5bee008e 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionListController.java +++ b/src/main/java/org/olat/modules/qpool/ui/QuestionListController.java @@ -57,12 +57,15 @@ import org.olat.core.gui.control.generic.wizard.StepRunnerCallback; import org.olat.core.gui.control.generic.wizard.StepsMainRunController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.core.id.Identity; +import org.olat.core.id.OLATResourceable; import org.olat.group.BusinessGroup; import org.olat.group.model.BusinessGroupSelectionEvent; import org.olat.group.ui.main.SelectBusinessGroupController; import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.ui.QuestionItemDataModel.Cols; +import org.olat.modules.qpool.ui.wizard.ImportAuthor_1_ChooseMemberStep; /** * @@ -82,7 +85,7 @@ public class QuestionListController extends FormBasicController implements Stack private SelectBusinessGroupController selectGroupCtrl; private CreateCollectionController createCollectionCtrl; private StepsMainRunController importAuthorsWizard; - private ImportQuestionItemController importItemCtrl; + private ImportController importItemCtrl; private final MarkManager markManager; private final QuestionPoolService qpoolService; @@ -155,34 +158,34 @@ public class QuestionListController extends FormBasicController implements Stack FormLink link = (FormLink)source; if(link == createList) { Set<Integer> selections = itemsTable.getMultiSelectedIndex(); - List<QuestionItem> items = getQuestionItems(selections); + List<QuestionItemShort> items = getShortItems(selections); doAskCollectionName(ureq, items); } else if(link == shareItem) { Set<Integer> selections = itemsTable.getMultiSelectedIndex(); if(selections.size() > 0) { - List<QuestionItem> items = getQuestionItems(selections); + List<QuestionItemShort> items = getShortItems(selections); doSelectGroup(ureq, items); } } else if(link == deleteItem) { Set<Integer> selections = itemsTable.getMultiSelectedIndex(); if(selections.size() > 0) { - List<QuestionItem> items = getQuestionItems(selections); + List<QuestionItemShort> items = getShortItems(selections); doConfirmDelete(ureq, items); } } else if(link == authorItem) { Set<Integer> selections = itemsTable.getMultiSelectedIndex(); if(selections.size() > 0) { - List<QuestionItem> items = getQuestionItems(selections); + List<QuestionItemShort> items = getShortItems(selections); doChooseAuthoren(ureq, items); } } else if(link == importItem) { doOpenImport(ureq); } else if("select".equals(link.getCmd())) { - QuestionItemRow row = (QuestionItemRow)link.getUserObject(); - doSelect(ureq, row.getItem()); + ItemRow row = (ItemRow)link.getUserObject(); + doSelect(ureq, row); } else if("mark".equals(link.getCmd())) { - QuestionItemRow row = (QuestionItemRow)link.getUserObject(); - if(doMark(ureq, row.getItem())) { + ItemRow row = (ItemRow)link.getUserObject(); + if(doMark(ureq, row)) { link.setI18nKey("Mark_true"); } else { link.setI18nKey("Mark_false"); @@ -193,11 +196,11 @@ public class QuestionListController extends FormBasicController implements Stack if(event instanceof SelectionEvent) { SelectionEvent se = (SelectionEvent)event; if("rSelect".equals(se.getCommand())) { - QuestionItemRow row = model.getObject(se.getIndex()); - fireEvent(ureq, new QuestionEvent(se.getCommand(), row.getItem())); + ItemRow row = model.getObject(se.getIndex()); + fireEvent(ureq, new QItemEvent(se.getCommand(), row)); } else if("select-item".equals(se.getCommand())) { - QuestionItemRow row = model.getObject(se.getIndex()); - doSelect(ureq, row.getItem()); + ItemRow row = model.getObject(se.getIndex()); + doSelect(ureq, row); } } } @@ -212,7 +215,7 @@ public class QuestionListController extends FormBasicController implements Stack List<BusinessGroup> groups = bge.getGroups(); if(groups.size() > 0) { @SuppressWarnings("unchecked") - List<QuestionItem> items = (List<QuestionItem>)selectGroupCtrl.getUserObject(); + List<QuestionItemShort> items = (List<QuestionItemShort>)selectGroupCtrl.getUserObject(); doShareItems(ureq, items, groups); } } @@ -221,7 +224,7 @@ public class QuestionListController extends FormBasicController implements Stack } else if(source == createCollectionCtrl) { if(Event.DONE_EVENT == event) { @SuppressWarnings("unchecked") - List<QuestionItem> items = (List<QuestionItem>)createCollectionCtrl.getUserObject(); + List<QuestionItemShort> items = (List<QuestionItemShort>)createCollectionCtrl.getUserObject(); String collectionName = createCollectionCtrl.getName(); doCreateCollection(ureq, collectionName, items); } @@ -243,7 +246,7 @@ public class QuestionListController extends FormBasicController implements Stack boolean delete = DialogBoxUIFactory.isYesEvent(event) || DialogBoxUIFactory.isOkEvent(event); if(delete) { @SuppressWarnings("unchecked") - List<QuestionItem> items = (List<QuestionItem>)confirmDeleteBox.getUserObject(); + List<QuestionItemShort> items = (List<QuestionItemShort>)confirmDeleteBox.getUserObject(); doDelete(ureq, items); } } else if(source == cmc) { @@ -263,28 +266,28 @@ public class QuestionListController extends FormBasicController implements Stack createCollectionCtrl = null; } - public List<QuestionItem> getQuestionItems(Set<Integer> index) { - List<QuestionItem> items = new ArrayList<QuestionItem>(); + public List<QuestionItemShort> getShortItems(Set<Integer> index) { + List<QuestionItemShort> items = new ArrayList<QuestionItemShort>(); for(Integer i:index) { - QuestionItemRow row = model.getObject(i.intValue()); + ItemRow row = model.getObject(i.intValue()); if(row != null) { - items.add(row.getItem()); + items.add(row); } } return items; } - public QuestionItem getQuestionItemAt(int index) { - QuestionItemRow row = model.getObject(index); + public QuestionItemShort getQuestionItemAt(int index) { + ItemRow row = model.getObject(index); if(row != null) { - return row.getItem(); + return qpoolService.loadItemById(row.getKey()); } return null; } private void doOpenImport(UserRequest ureq) { removeAsListenerAndDispose(importItemCtrl); - importItemCtrl = new ImportQuestionItemController(ureq, getWindowControl()); + importItemCtrl = new ImportController(ureq, getWindowControl()); listenTo(importItemCtrl); cmc = new CloseableModalController(getWindowControl(), translate("close"), @@ -293,7 +296,7 @@ public class QuestionListController extends FormBasicController implements Stack listenTo(cmc); } - private void doAskCollectionName(UserRequest ureq, List<QuestionItem> items) { + private void doAskCollectionName(UserRequest ureq, List<QuestionItemShort> items) { removeAsListenerAndDispose(createCollectionCtrl); createCollectionCtrl = new CreateCollectionController(ureq, getWindowControl()); createCollectionCtrl.setUserObject(items); @@ -305,12 +308,12 @@ public class QuestionListController extends FormBasicController implements Stack listenTo(cmc); } - private void doCreateCollection(UserRequest ureq, String name, List<QuestionItem> items) { + private void doCreateCollection(UserRequest ureq, String name, List<QuestionItemShort> items) { qpoolService.createCollection(getIdentity(), name, items); fireEvent(ureq, new QPoolEvent(QPoolEvent.COLL_CREATED)); } - private void doChooseAuthoren(UserRequest ureq, List<QuestionItem> items) { + private void doChooseAuthoren(UserRequest ureq, List<QuestionItemShort> items) { removeAsListenerAndDispose(importAuthorsWizard); Step start = new ImportAuthor_1_ChooseMemberStep(ureq, items); @@ -330,24 +333,24 @@ public class QuestionListController extends FormBasicController implements Stack private void addAuthors(UserRequest ureq, StepsRunContext runContext) { @SuppressWarnings("unchecked") - List<QuestionItem> items = (List<QuestionItem>)runContext.get("items"); + List<QuestionItemShort> items = (List<QuestionItemShort>)runContext.get("items"); @SuppressWarnings("unchecked") List<Identity> authors = (List<Identity>)runContext.get("members"); qpoolService.addAuthors(authors, items); } - private void doConfirmDelete(UserRequest ureq, List<QuestionItem> items) { + private void doConfirmDelete(UserRequest ureq, List<QuestionItemShort> items) { confirmDeleteBox = activateYesNoDialog(ureq, null, translate("confirm.delete"), confirmDeleteBox); confirmDeleteBox.setUserObject(items); } - private void doDelete(UserRequest ureq, List<QuestionItem> items) { + private void doDelete(UserRequest ureq, List<QuestionItemShort> items) { qpoolService.deleteItems(items); itemsTable.reset(); showInfo("item.deleted"); } - protected void doSelectGroup(UserRequest ureq, List<QuestionItem> items) { + protected void doSelectGroup(UserRequest ureq, List<QuestionItemShort> items) { removeAsListenerAndDispose(selectGroupCtrl); selectGroupCtrl = new SelectBusinessGroupController(ureq, getWindowControl()); selectGroupCtrl.setUserObject(items); @@ -359,23 +362,24 @@ public class QuestionListController extends FormBasicController implements Stack listenTo(cmc); } - private void doShareItems(UserRequest ureq, List<QuestionItem> items, List<BusinessGroup> groups) { + private void doShareItems(UserRequest ureq, List<QuestionItemShort> items, List<BusinessGroup> groups) { qpoolService.shareItems(items, groups); fireEvent(ureq, new QPoolEvent(QPoolEvent.ITEM_SHARED)); } - protected void doSelect(UserRequest ureq, QuestionItem item) { + protected void doSelect(UserRequest ureq, ItemRow row) { + QuestionItem item = qpoolService.loadItemById(row.getKey()); QuestionItemDetailsController detailsCtrl = new QuestionItemDetailsController(ureq, getWindowControl(), item); LayoutMain3ColsController mainCtrl = new LayoutMain3ColsController(ureq, getWindowControl(), detailsCtrl); stackPanel.pushController(item.getTitle(), mainCtrl); } - protected boolean doMark(UserRequest ureq, QuestionItem item) { + protected boolean doMark(UserRequest ureq, OLATResourceable item) { if(markManager.isMarked(item, getIdentity(), null)) { markManager.deleteMark(item); return false; } else { - String businessPath = "[QuestionItem:" + item.getKey() + "]"; + String businessPath = "[QuestionItem:" + item.getResourceableId() + "]"; markManager.setMark(item, getIdentity(), null, businessPath); return true; } @@ -387,22 +391,22 @@ public class QuestionListController extends FormBasicController implements Stack } @Override - public ResultInfos<QuestionItemRow> getRows(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { + public ResultInfos<ItemRow> getRows(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { Set<Long> marks = markManager.getMarkResourceIds(getIdentity(), "QuestionItem", Collections.<String>emptyList()); - ResultInfos<QuestionItem> items = source.getItems(query, condQueries, firstResult, maxResults, orderBy); - List<QuestionItemRow> rows = new ArrayList<QuestionItemRow>(items.getObjects().size()); - for(QuestionItem item:items.getObjects()) { - QuestionItemRow row = forgeRow(item, marks); + ResultInfos<QuestionItemShort> items = source.getItems(query, condQueries, firstResult, maxResults, orderBy); + List<ItemRow> rows = new ArrayList<ItemRow>(items.getObjects().size()); + for(QuestionItemShort item:items.getObjects()) { + ItemRow row = forgeRow(item, marks); rows.add(row); } - return new DefaultResultInfos<QuestionItemRow>(items.getNextFirstResult(), items.getCorrectedRowCount(), rows); + return new DefaultResultInfos<ItemRow>(items.getNextFirstResult(), items.getCorrectedRowCount(), rows); } - protected QuestionItemRow forgeRow(QuestionItem item, Set<Long> markedQuestionKeys) { + protected ItemRow forgeRow(QuestionItemShort item, Set<Long> markedQuestionKeys) { boolean marked = markedQuestionKeys.contains(item.getKey()); - QuestionItemRow row = new QuestionItemRow(item); + ItemRow row = new ItemRow(item); FormLink markLink = uifactory.addFormLink("mark_" + row.getKey(), "mark", "Mark_" + marked, null, null, Link.NONTRANSLATED); markLink.setUserObject(row); row.setMarkLink(markLink); diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMainEditorController.java b/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMainEditorController.java index e0d3990220f..4219ffe519b 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMainEditorController.java +++ b/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMainEditorController.java @@ -44,9 +44,14 @@ import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.group.BusinessGroup; import org.olat.modules.qpool.Pool; -import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItemCollection; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; +import org.olat.modules.qpool.ui.datasource.CollectionOfItemsSource; +import org.olat.modules.qpool.ui.datasource.MarkedItemsSource; +import org.olat.modules.qpool.ui.datasource.MyQuestionItemsSource; +import org.olat.modules.qpool.ui.datasource.PooledItemsSource; +import org.olat.modules.qpool.ui.datasource.SharedItemsSource; /** * @@ -70,7 +75,7 @@ public class QuestionPoolMainEditorController extends BasicController implements private QuestionsController markedQuestionsCtrl; private PoolsAdminController poolAdminCtrl; - private StudyFieldAdminController studyFieldCtrl; + private TaxonomyAdminController studyFieldCtrl; private LayoutMain3ColsController columnLayoutCtr; private QuestionPoolAdminStatisticsController adminStatisticsCtrl; @@ -86,7 +91,9 @@ public class QuestionPoolMainEditorController extends BasicController implements menuTree = new MenuTree("qpoolTree"); menuTree.setTreeModel(buildTreeModel()); menuTree.setSelectedNode(menuTree.getTreeModel().getRootNode()); + menuTree.setDragEnabled(false); menuTree.setDropEnabled(true); + menuTree.setDropSiblingEnabled(false); menuTree.addListener(this); menuTree.setRootVisible(false); @@ -173,7 +180,7 @@ public class QuestionPoolMainEditorController extends BasicController implements int lastIndex = dropId.lastIndexOf('-'); String rowStr = dropId.substring(lastIndex+1, dropId.length()); int row = Integer.parseInt(rowStr); - QuestionItem item = currentCtrl.getQuestionAt(row); + QuestionItemShort item = currentCtrl.getQuestionAt(row); TreeNode node = menuTree.getTreeModel().getNodeById(targetId); if(node != null) { Object userObj = node.getUserObject(); @@ -207,7 +214,7 @@ public class QuestionPoolMainEditorController extends BasicController implements private void doSelectAdminStudyFields(UserRequest ureq) { if(studyFieldCtrl == null) { - studyFieldCtrl = new StudyFieldAdminController(ureq, getWindowControl()); + studyFieldCtrl = new TaxonomyAdminController(ureq, getWindowControl()); listenTo(studyFieldCtrl); } content.setContent(studyFieldCtrl.getInitialComponent()); diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMenuTreeModel.java b/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMenuTreeModel.java index 5b89cde2980..b9b6063f52b 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMenuTreeModel.java +++ b/src/main/java/org/olat/modules/qpool/ui/QuestionPoolMenuTreeModel.java @@ -22,6 +22,9 @@ package org.olat.modules.qpool.ui; import org.olat.core.gui.components.tree.DnDTreeModel; import org.olat.core.gui.components.tree.GenericTreeModel; import org.olat.core.gui.components.tree.TreeNode; +import org.olat.group.BusinessGroup; +import org.olat.modules.qpool.Pool; +import org.olat.modules.qpool.QuestionItemCollection; /** * @@ -35,6 +38,20 @@ public class QuestionPoolMenuTreeModel extends GenericTreeModel implements DnDTr @Override public boolean canDrop(TreeNode droppedNode, TreeNode targetNode, boolean sibling) { - return !sibling; + if(droppedNode == null && targetNode == null) { + return false; + } else if(droppedNode == null) { + Object uObject = targetNode.getUserObject(); + if("menu.database.my".equals(uObject) + || "menu.database.favorit".equals(uObject)) { + return !sibling; + } else if(uObject instanceof BusinessGroup + || uObject instanceof QuestionItemCollection + || uObject instanceof Pool) { + return !sibling; + } + return false; + } + return false; } } diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionsController.java b/src/main/java/org/olat/modules/qpool/ui/QuestionsController.java index b7ed96a4ad7..5669bd57728 100644 --- a/src/main/java/org/olat/modules/qpool/ui/QuestionsController.java +++ b/src/main/java/org/olat/modules/qpool/ui/QuestionsController.java @@ -38,6 +38,7 @@ import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; /** @@ -95,7 +96,7 @@ public class QuestionsController extends BasicController implements StackedContr listCtrl.updateSource(source); } - public QuestionItem getQuestionAt(int index) { + public QuestionItemShort getQuestionAt(int index) { return listCtrl.getQuestionItemAt(index); } @@ -117,9 +118,9 @@ public class QuestionsController extends BasicController implements StackedContr @Override protected void event(UserRequest ureq, Controller source, Event event) { if(source == listCtrl) { - if(event instanceof QuestionEvent) { - QuestionEvent se = (QuestionEvent)event; - QuestionItem item = se.getItem(); + if(event instanceof QItemEvent) { + QItemEvent se = (QItemEvent)event; + QuestionItemShort item = se.getItem(); doUpdateDetails(ureq, item); } else if(event instanceof QPoolEvent) { fireEvent(ureq, event); @@ -155,12 +156,13 @@ public class QuestionsController extends BasicController implements StackedContr confirmDeleteBox.setUserObject(item); } - private void doUpdateDetails(UserRequest ureq, QuestionItem item) { + private void doUpdateDetails(UserRequest ureq, QuestionItemShort itemShort) { + QuestionItem item = qpoolService.loadItemById(itemShort.getKey()); detailsCtrl.updateItem(item); previewCtrl.updateItem(ureq, item); } - private void doDelete(UserRequest ureq, QuestionItem item) { + private void doDelete(UserRequest ureq, QuestionItemShort item) { qpoolService.deleteItems(Collections.singletonList(item)); postDelete(ureq); } diff --git a/src/main/java/org/olat/modules/qpool/ui/StudyFieldAdminController.java b/src/main/java/org/olat/modules/qpool/ui/TaxonomyAdminController.java similarity index 88% rename from src/main/java/org/olat/modules/qpool/ui/StudyFieldAdminController.java rename to src/main/java/org/olat/modules/qpool/ui/TaxonomyAdminController.java index 3abdc2b49fc..50026cd620b 100644 --- a/src/main/java/org/olat/modules/qpool/ui/StudyFieldAdminController.java +++ b/src/main/java/org/olat/modules/qpool/ui/TaxonomyAdminController.java @@ -33,21 +33,21 @@ import org.olat.core.gui.control.controller.BasicController; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class StudyFieldAdminController extends BasicController { +public class TaxonomyAdminController extends BasicController { private final MenuTree studyFieldTree; - private final StudyFieldTreeModel studyFieldTreeModel; + private final TaxonomyTreeModel studyFieldTreeModel; private final VelocityContainer mainVC; - public StudyFieldAdminController(UserRequest ureq, WindowControl wControl) { + public TaxonomyAdminController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); mainVC = createVelocityContainer("admin_study_fields"); studyFieldTree = new MenuTree("qpoolTree"); - studyFieldTreeModel = new StudyFieldTreeModel(); + studyFieldTreeModel = new TaxonomyTreeModel(); studyFieldTree.setTreeModel(studyFieldTreeModel); studyFieldTree.setSelectedNode(studyFieldTree.getTreeModel().getRootNode()); studyFieldTree.setDropEnabled(false); diff --git a/src/main/java/org/olat/modules/qpool/ui/StudyFieldTreeModel.java b/src/main/java/org/olat/modules/qpool/ui/TaxonomyTreeModel.java similarity index 96% rename from src/main/java/org/olat/modules/qpool/ui/StudyFieldTreeModel.java rename to src/main/java/org/olat/modules/qpool/ui/TaxonomyTreeModel.java index da1e08da14a..e791dfe2cd6 100644 --- a/src/main/java/org/olat/modules/qpool/ui/StudyFieldTreeModel.java +++ b/src/main/java/org/olat/modules/qpool/ui/TaxonomyTreeModel.java @@ -35,12 +35,12 @@ import org.olat.modules.qpool.TaxonomyLevel; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class StudyFieldTreeModel extends GenericTreeModel { +public class TaxonomyTreeModel extends GenericTreeModel { private static final long serialVersionUID = 3032222581990406868L; private QuestionPoolService qpoolService; - public StudyFieldTreeModel() { + public TaxonomyTreeModel() { qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); buildTree(); diff --git a/src/main/java/org/olat/modules/qpool/ui/_content/item_details.html b/src/main/java/org/olat/modules/qpool/ui/_content/item_details.html index c28b62c3a6d..4d2157c43d1 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_content/item_details.html +++ b/src/main/java/org/olat/modules/qpool/ui/_content/item_details.html @@ -3,7 +3,6 @@ $r.render("type_specifics") $r.render("metadatas") <div class="b_clearfix o_qpool_button_bar_box"> <div class="o_qpool_button_bar"> - $r.render("save") $r.render("share.item") $r.render("delete.item") </div> diff --git a/src/main/java/org/olat/modules/qpool/ui/_content/items.html b/src/main/java/org/olat/modules/qpool/ui/_content/items.html index 6115b4061f4..875dc86d34f 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_content/items.html +++ b/src/main/java/org/olat/modules/qpool/ui/_content/items.html @@ -1,4 +1,4 @@ -<div id="container"> +<div id="qpoolcontainer"> <div id="qitems" class="pane ui-layout-north">$r.render("items")</div> <div id="qdetails" class="pane ui-layout-center">$r.render("details")</div> <div id="qpreview" class="pane ui-layout-west">$r.render("preview")</div> @@ -9,11 +9,15 @@ $r.render("delete.item") </div> </div> -<script> +<script type="text/javascript"> jQuery(function() { var width = jQuery('#b_col3_content_inner').width(); - var height = jQuery('#b_col3_content_inner').height(); - jQuery('#container').width(width).height(height).layout({ + var winHeight = jQuery(window).height(); + var headerHeight = jQuery('#b_header').height() + jQuery('#b_nav_main').height(); + var footerHeight = jQuery('#b_footer').height() + jQuery('#qbuttons').height(); + var maxHeight = winHeight - headerHeight - footerHeight - 50; + jQuery('#qpoolcontainer').width(width).height(maxHeight).layout({ + north: { size: '50%' }, center: { size: '50%' }, west: { size: '50%' }, south: {} diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties index 3b1b96c637d..d3cad98ea78 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties @@ -103,7 +103,6 @@ item.type.essay=Essay author.item=Authoren author.choose.title=Authoren auswählen author.confirm.title=Bestätigen -table.user.login=$org.olat.admin.user\:table.user.login share.item=Freigeben select.group=Freigeben select.item=Bearbeiten diff --git a/src/main/java/org/olat/modules/qpool/ui/CollectionOfItemsSource.java b/src/main/java/org/olat/modules/qpool/ui/datasource/CollectionOfItemsSource.java similarity index 88% rename from src/main/java/org/olat/modules/qpool/ui/CollectionOfItemsSource.java rename to src/main/java/org/olat/modules/qpool/ui/datasource/CollectionOfItemsSource.java index 3df610d468c..eb3716a4013 100644 --- a/src/main/java/org/olat/modules/qpool/ui/CollectionOfItemsSource.java +++ b/src/main/java/org/olat/modules/qpool/ui/datasource/CollectionOfItemsSource.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.datasource; import java.util.List; @@ -26,10 +26,11 @@ import org.olat.core.commons.persistence.ResultInfos; import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.core.id.Roles; -import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItemCollection; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.SearchQuestionItemParams; +import org.olat.modules.qpool.ui.QuestionItemsSource; /** * @@ -57,7 +58,7 @@ public class CollectionOfItemsSource implements QuestionItemsSource { } @Override - public ResultInfos<QuestionItem> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { + public ResultInfos<QuestionItemShort> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { SearchQuestionItemParams params = new SearchQuestionItemParams(identity, roles); params.setSearchString(query); return qpoolService.getItemsOfCollection(collection, params, firstResult, maxResults); diff --git a/src/main/java/org/olat/modules/qpool/ui/MarkedItemsSource.java b/src/main/java/org/olat/modules/qpool/ui/datasource/MarkedItemsSource.java similarity index 86% rename from src/main/java/org/olat/modules/qpool/ui/MarkedItemsSource.java rename to src/main/java/org/olat/modules/qpool/ui/datasource/MarkedItemsSource.java index e707dbf1369..d129a377433 100644 --- a/src/main/java/org/olat/modules/qpool/ui/MarkedItemsSource.java +++ b/src/main/java/org/olat/modules/qpool/ui/datasource/MarkedItemsSource.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.datasource; import java.util.List; @@ -26,9 +26,10 @@ import org.olat.core.commons.persistence.ResultInfos; import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.core.id.Roles; -import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.SearchQuestionItemParams; +import org.olat.modules.qpool.ui.QuestionItemsSource; /** * @@ -54,7 +55,7 @@ public class MarkedItemsSource implements QuestionItemsSource { } @Override - public ResultInfos<QuestionItem> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { + public ResultInfos<QuestionItemShort> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { SearchQuestionItemParams params = new SearchQuestionItemParams(me, roles); params.setSearchString(query); return qpoolService.getFavoritItems(me, params, firstResult, maxResults); diff --git a/src/main/java/org/olat/modules/qpool/ui/MyQuestionItemsSource.java b/src/main/java/org/olat/modules/qpool/ui/datasource/MyQuestionItemsSource.java similarity index 86% rename from src/main/java/org/olat/modules/qpool/ui/MyQuestionItemsSource.java rename to src/main/java/org/olat/modules/qpool/ui/datasource/MyQuestionItemsSource.java index 921422d0adc..d77c772a98e 100644 --- a/src/main/java/org/olat/modules/qpool/ui/MyQuestionItemsSource.java +++ b/src/main/java/org/olat/modules/qpool/ui/datasource/MyQuestionItemsSource.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.datasource; import java.util.List; @@ -26,9 +26,10 @@ import org.olat.core.commons.persistence.ResultInfos; import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.core.id.Roles; -import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.SearchQuestionItemParams; +import org.olat.modules.qpool.ui.QuestionItemsSource; /** * @@ -54,7 +55,7 @@ public class MyQuestionItemsSource implements QuestionItemsSource { } @Override - public ResultInfos<QuestionItem> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { + public ResultInfos<QuestionItemShort> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { SearchQuestionItemParams params = new SearchQuestionItemParams(me, roles); params.setSearchString(query); return qpoolService.getItems(me, params, firstResult, maxResults); diff --git a/src/main/java/org/olat/modules/qpool/ui/PooledItemsSource.java b/src/main/java/org/olat/modules/qpool/ui/datasource/PooledItemsSource.java similarity index 87% rename from src/main/java/org/olat/modules/qpool/ui/PooledItemsSource.java rename to src/main/java/org/olat/modules/qpool/ui/datasource/PooledItemsSource.java index d6562ea66e3..06362cd7056 100644 --- a/src/main/java/org/olat/modules/qpool/ui/PooledItemsSource.java +++ b/src/main/java/org/olat/modules/qpool/ui/datasource/PooledItemsSource.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.datasource; import java.util.List; @@ -27,9 +27,10 @@ import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.modules.qpool.Pool; -import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.SearchQuestionItemParams; +import org.olat.modules.qpool.ui.QuestionItemsSource; /** * @@ -57,7 +58,7 @@ public class PooledItemsSource implements QuestionItemsSource { } @Override - public ResultInfos<QuestionItem> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { + public ResultInfos<QuestionItemShort> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { SearchQuestionItemParams params = new SearchQuestionItemParams(identity, roles); params.setSearchString(query); return qpoolService.getItemsOfPool(pool, params, firstResult, maxResults, orderBy); diff --git a/src/main/java/org/olat/modules/qpool/ui/SharedItemsSource.java b/src/main/java/org/olat/modules/qpool/ui/datasource/SharedItemsSource.java similarity index 88% rename from src/main/java/org/olat/modules/qpool/ui/SharedItemsSource.java rename to src/main/java/org/olat/modules/qpool/ui/datasource/SharedItemsSource.java index 3621046b36d..fe7e7fb73c4 100644 --- a/src/main/java/org/olat/modules/qpool/ui/SharedItemsSource.java +++ b/src/main/java/org/olat/modules/qpool/ui/datasource/SharedItemsSource.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.datasource; import java.util.List; @@ -27,9 +27,10 @@ import org.olat.core.commons.persistence.SortKey; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.group.BusinessGroup; -import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.SearchQuestionItemParams; +import org.olat.modules.qpool.ui.QuestionItemsSource; import org.olat.resource.OLATResource; /** @@ -58,7 +59,7 @@ public class SharedItemsSource implements QuestionItemsSource { } @Override - public ResultInfos<QuestionItem> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { + public ResultInfos<QuestionItemShort> getItems(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy) { SearchQuestionItemParams params = new SearchQuestionItemParams(identity, roles); params.setSearchString(query); return qpoolService.getSharedItemByResource(resource, params, firstResult, maxResults, orderBy); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/EducationalMetadataController.java b/src/main/java/org/olat/modules/qpool/ui/edit/EducationalMetadataController.java index 9961501844f..861e718a512 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/EducationalMetadataController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/EducationalMetadataController.java @@ -33,7 +33,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.ui.QPoolEvent; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -48,7 +48,7 @@ public class EducationalMetadataController extends FormBasicController { public EducationalMetadataController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl, "view"); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); initForm(ureq); setItem(item); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/EducationalMetadataEditController.java b/src/main/java/org/olat/modules/qpool/ui/edit/EducationalMetadataEditController.java index c1e1e083806..43dcb73ff31 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/EducationalMetadataEditController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/EducationalMetadataEditController.java @@ -33,7 +33,7 @@ import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.QuestionItemImpl; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -52,7 +52,7 @@ public class EducationalMetadataEditController extends FormBasicController { public EducationalMetadataEditController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); this.item = item; qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/GeneralMetadataController.java b/src/main/java/org/olat/modules/qpool/ui/edit/GeneralMetadataController.java index a7b2c27968d..1ef3cfa2055 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/GeneralMetadataController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/GeneralMetadataController.java @@ -35,7 +35,7 @@ import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.ui.QPoolEvent; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -52,7 +52,7 @@ public class GeneralMetadataController extends FormBasicController { public GeneralMetadataController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl, "view"); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/GeneralMetadataEditController.java b/src/main/java/org/olat/modules/qpool/ui/edit/GeneralMetadataEditController.java index 65802a7155d..13772209fa3 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/GeneralMetadataEditController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/GeneralMetadataEditController.java @@ -34,7 +34,7 @@ import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.QuestionItemImpl; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -52,7 +52,7 @@ public class GeneralMetadataEditController extends FormBasicController { public GeneralMetadataEditController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); this.item = item; qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/LifecycleMetadataController.java b/src/main/java/org/olat/modules/qpool/ui/edit/LifecycleMetadataController.java index 267fd853b6b..5eba4fa926d 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/LifecycleMetadataController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/LifecycleMetadataController.java @@ -34,7 +34,7 @@ import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionStatus; import org.olat.modules.qpool.ui.QPoolEvent; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -49,7 +49,7 @@ public class LifecycleMetadataController extends FormBasicController { public LifecycleMetadataController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl, "view"); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); initForm(ureq); setItem(item); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/LifecycleMetadataEditController.java b/src/main/java/org/olat/modules/qpool/ui/edit/LifecycleMetadataEditController.java index 0ffd9a2ec43..3abae783254 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/LifecycleMetadataEditController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/LifecycleMetadataEditController.java @@ -35,7 +35,7 @@ import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.QuestionStatus; import org.olat.modules.qpool.model.QuestionItemImpl; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -53,7 +53,7 @@ public class LifecycleMetadataEditController extends FormBasicController { public LifecycleMetadataEditController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); this.item = item; qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/QuestionMetadataController.java b/src/main/java/org/olat/modules/qpool/ui/edit/QuestionMetadataController.java index dd0bd88370d..7a84a79db5a 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/QuestionMetadataController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/QuestionMetadataController.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.modules.qpool.ui.edit; import java.math.BigDecimal; @@ -16,7 +35,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.ui.QPoolEvent; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -31,7 +50,7 @@ public class QuestionMetadataController extends FormBasicController { public QuestionMetadataController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl, "view"); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); initForm(ureq); setItem(item); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/QuestionMetadataEditController.java b/src/main/java/org/olat/modules/qpool/ui/edit/QuestionMetadataEditController.java index e5304103dc8..d487464ab39 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/QuestionMetadataEditController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/QuestionMetadataEditController.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.modules.qpool.ui.edit; import java.math.BigDecimal; @@ -17,7 +36,7 @@ import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.QuestionItemImpl; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -35,7 +54,7 @@ public class QuestionMetadataEditController extends FormBasicController { public QuestionMetadataEditController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); this.item = item; qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/RightsMetadataController.java b/src/main/java/org/olat/modules/qpool/ui/edit/RightsMetadataController.java index b45322bd67f..fc8287f6520 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/RightsMetadataController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/RightsMetadataController.java @@ -35,7 +35,7 @@ import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.ui.QPoolEvent; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -51,7 +51,7 @@ public class RightsMetadataController extends FormBasicController { public RightsMetadataController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl, "view"); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); initForm(ureq); setItem(item); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/RightsMetadataEditController.java b/src/main/java/org/olat/modules/qpool/ui/edit/RightsMetadataEditController.java index 001ecce745b..7719138207e 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/RightsMetadataEditController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/RightsMetadataEditController.java @@ -38,7 +38,7 @@ import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.QuestionItemImpl; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -67,7 +67,7 @@ public class RightsMetadataEditController extends FormBasicController { public RightsMetadataEditController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); this.item = item; qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/TechnicalMetadataController.java b/src/main/java/org/olat/modules/qpool/ui/edit/TechnicalMetadataController.java index 0648d190c0a..dee4cce6234 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/TechnicalMetadataController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/TechnicalMetadataController.java @@ -34,7 +34,7 @@ import org.olat.core.util.Formatter; import org.olat.core.util.Util; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.ui.QPoolEvent; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -49,7 +49,7 @@ public class TechnicalMetadataController extends FormBasicController { public TechnicalMetadataController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl, "view"); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); initForm(ureq); setItem(item); diff --git a/src/main/java/org/olat/modules/qpool/ui/edit/TechnicalMetadataEditController.java b/src/main/java/org/olat/modules/qpool/ui/edit/TechnicalMetadataEditController.java index bbaa9c67da4..1a6c3533b1c 100644 --- a/src/main/java/org/olat/modules/qpool/ui/edit/TechnicalMetadataEditController.java +++ b/src/main/java/org/olat/modules/qpool/ui/edit/TechnicalMetadataEditController.java @@ -36,7 +36,7 @@ import org.olat.ims.qti.QTIConstants; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.model.QuestionItemImpl; -import org.olat.modules.qpool.ui.QuestionItemMetadatasController; +import org.olat.modules.qpool.ui.MetadatasController; /** * @@ -54,7 +54,7 @@ public class TechnicalMetadataEditController extends FormBasicController { public TechnicalMetadataEditController(UserRequest ureq, WindowControl wControl, QuestionItem item) { super(ureq, wControl); - setTranslator(Util.createPackageTranslator(QuestionItemMetadatasController.class, ureq.getLocale(), getTranslator())); + setTranslator(Util.createPackageTranslator(MetadatasController.class, ureq.getLocale(), getTranslator())); this.item = item; qpoolService = CoreSpringFactory.getImpl(QuestionPoolService.class); diff --git a/src/main/java/org/olat/modules/qpool/ui/ImportAuthorBySearchController.java b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorBySearchController.java similarity index 98% rename from src/main/java/org/olat/modules/qpool/ui/ImportAuthorBySearchController.java rename to src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorBySearchController.java index 1ebde6cc6ba..a21e6f41da8 100644 --- a/src/main/java/org/olat/modules/qpool/ui/ImportAuthorBySearchController.java +++ b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorBySearchController.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.wizard; import java.util.ArrayList; import java.util.Collection; diff --git a/src/main/java/org/olat/modules/qpool/ui/ImportAuthorOverviewDataModel.java b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorOverviewDataModel.java similarity index 98% rename from src/main/java/org/olat/modules/qpool/ui/ImportAuthorOverviewDataModel.java rename to src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorOverviewDataModel.java index 84c80e8ff51..9f5eede4204 100644 --- a/src/main/java/org/olat/modules/qpool/ui/ImportAuthorOverviewDataModel.java +++ b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorOverviewDataModel.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.wizard; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/olat/modules/qpool/ui/ImportAuthorOverviewIdentitiesController.java b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorOverviewIdentitiesController.java similarity index 99% rename from src/main/java/org/olat/modules/qpool/ui/ImportAuthorOverviewIdentitiesController.java rename to src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorOverviewIdentitiesController.java index a2b9608fd6e..e552fff04d5 100644 --- a/src/main/java/org/olat/modules/qpool/ui/ImportAuthorOverviewIdentitiesController.java +++ b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthorOverviewIdentitiesController.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.wizard; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/org/olat/modules/qpool/ui/ImportAuthor_1_ChooseMemberStep.java b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthor_1_ChooseMemberStep.java similarity index 92% rename from src/main/java/org/olat/modules/qpool/ui/ImportAuthor_1_ChooseMemberStep.java rename to src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthor_1_ChooseMemberStep.java index d2188b49284..a4774a19506 100644 --- a/src/main/java/org/olat/modules/qpool/ui/ImportAuthor_1_ChooseMemberStep.java +++ b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthor_1_ChooseMemberStep.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.wizard; import java.util.List; @@ -28,7 +28,7 @@ import org.olat.core.gui.control.generic.wizard.BasicStep; import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig; import org.olat.core.gui.control.generic.wizard.StepFormController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; -import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; /** * @@ -38,9 +38,9 @@ import org.olat.modules.qpool.QuestionItem; */ public class ImportAuthor_1_ChooseMemberStep extends BasicStep { - private final List<QuestionItem> items; + private final List<QuestionItemShort> items; - public ImportAuthor_1_ChooseMemberStep(UserRequest ureq, List<QuestionItem> items) { + public ImportAuthor_1_ChooseMemberStep(UserRequest ureq, List<QuestionItemShort> items) { super(ureq); this.items = items; setNextStep(new ImportAuthor_2_ConfirmMemberChoiceStep(ureq)); diff --git a/src/main/java/org/olat/modules/qpool/ui/ImportAuthor_2_ConfirmMemberChoiceStep.java b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthor_2_ConfirmMemberChoiceStep.java similarity index 97% rename from src/main/java/org/olat/modules/qpool/ui/ImportAuthor_2_ConfirmMemberChoiceStep.java rename to src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthor_2_ConfirmMemberChoiceStep.java index 66c69b79450..88b43871373 100644 --- a/src/main/java/org/olat/modules/qpool/ui/ImportAuthor_2_ConfirmMemberChoiceStep.java +++ b/src/main/java/org/olat/modules/qpool/ui/wizard/ImportAuthor_2_ConfirmMemberChoiceStep.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.modules.qpool.ui; +package org.olat.modules.qpool.ui.wizard; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.impl.Form; diff --git a/src/main/java/org/olat/modules/qpool/ui/_content/import_search.html b/src/main/java/org/olat/modules/qpool/ui/wizard/_content/import_search.html similarity index 100% rename from src/main/java/org/olat/modules/qpool/ui/_content/import_search.html rename to src/main/java/org/olat/modules/qpool/ui/wizard/_content/import_search.html diff --git a/src/main/java/org/olat/modules/qpool/ui/wizard/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/wizard/_i18n/LocalStrings_de.properties new file mode 100644 index 00000000000..07b63e8ca57 --- /dev/null +++ b/src/main/java/org/olat/modules/qpool/ui/wizard/_i18n/LocalStrings_de.properties @@ -0,0 +1,5 @@ +#Mon Mar 02 09:54:04 CET 2009 +author.item=Authoren +author.choose.title=Authoren auswählen +author.confirm.title=Bestätigen +table.user.login=$org.olat.admin.user\:table.user.login \ No newline at end of file diff --git a/src/main/java/org/olat/modules/qpool/ui/wizard/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/qpool/ui/wizard/_i18n/LocalStrings_en.properties new file mode 100644 index 00000000000..a008421f6a7 --- /dev/null +++ b/src/main/java/org/olat/modules/qpool/ui/wizard/_i18n/LocalStrings_en.properties @@ -0,0 +1,2 @@ +#Sun Jan 31 17:38:12 CET 2010 + diff --git a/src/main/java/org/olat/search/service/SearchServiceImpl.java b/src/main/java/org/olat/search/service/SearchServiceImpl.java index 2394444e050..64dc6104100 100644 --- a/src/main/java/org/olat/search/service/SearchServiceImpl.java +++ b/src/main/java/org/olat/search/service/SearchServiceImpl.java @@ -60,7 +60,7 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.ArrayHelper; import org.olat.core.util.StringHelper; -import org.olat.modules.qpool.model.QuestionItemDocument; +import org.olat.modules.qpool.model.QItemDocument; import org.olat.search.QueryException; import org.olat.search.SearchModule; import org.olat.search.SearchResults; @@ -109,7 +109,7 @@ public class SearchServiceImpl implements SearchService { AbstractOlatDocument.TITLE_FIELD_NAME, AbstractOlatDocument.DESCRIPTION_FIELD_NAME, AbstractOlatDocument.CONTENT_FIELD_NAME, AbstractOlatDocument.AUTHOR_FIELD_NAME, AbstractOlatDocument.DOCUMENTTYPE_FIELD_NAME, AbstractOlatDocument.FILETYPE_FIELD_NAME, - QuestionItemDocument.STUDY_FIELD + QItemDocument.STUDY_FIELD }; diff --git a/src/main/java/org/olat/search/service/indexer/QuestionItemIndexer.java b/src/main/java/org/olat/search/service/indexer/QuestionItemIndexer.java index e03e02bd951..bb0e7d62a1a 100644 --- a/src/main/java/org/olat/search/service/indexer/QuestionItemIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/QuestionItemIndexer.java @@ -29,7 +29,7 @@ import org.olat.core.logging.Tracing; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.manager.QuestionItemDocumentFactory; -import org.olat.modules.qpool.model.QuestionItemDocument; +import org.olat.modules.qpool.model.QItemDocument; import org.olat.search.service.SearchResourceContext; /** @@ -44,7 +44,7 @@ public class QuestionItemIndexer implements LifeIndexer { @Override public String getSupportedTypeName() { - return QuestionItemDocument.TYPE; + return QItemDocument.TYPE; } @Override diff --git a/src/test/java/org/olat/ims/qti/qpool/QTIImportProcessorTest.java b/src/test/java/org/olat/ims/qti/qpool/QTIImportProcessorTest.java new file mode 100644 index 00000000000..71b7290bfe2 --- /dev/null +++ b/src/test/java/org/olat/ims/qti/qpool/QTIImportProcessorTest.java @@ -0,0 +1,144 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.ims.qti.qpool; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; + +import junit.framework.Assert; + +import org.jgroups.util.UUID; +import org.junit.Before; +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.ims.qti.QTIConstants; +import org.olat.ims.qti.qpool.QTIImportProcessor.DocInfos; +import org.olat.ims.qti.qpool.QTIImportProcessor.ItemInfos; +import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionStatus; +import org.olat.modules.qpool.QuestionType; +import org.olat.modules.qpool.manager.QuestionItemDAO; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 08.03.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class QTIImportProcessorTest extends OlatTestCase { + + private static Identity owner; + + @Autowired + private DB dbInstance; + @Autowired + private QuestionItemDAO questionItemDao; + + @Before + public void setup() { + if(owner == null) { + owner = JunitTestHelper.createAndPersistIdentityAsUser("QTI-imp-owner-" + UUID.randomUUID().toString()); + } + } + + @Test + public void testImport_SC() throws IOException, URISyntaxException { + URL itemUrl = QTIImportProcessorTest.class.getResource("mchc_i_002.xml"); + Assert.assertNotNull(itemUrl); + File itemFile = new File(itemUrl.toURI()); + + //get the document informations + QTIImportProcessor proc = new QTIImportProcessor(owner, itemFile.getName(), itemFile, questionItemDao); + DocInfos docInfos = proc.getDocInfos(); + Assert.assertNotNull(docInfos); + Assert.assertNotNull(docInfos.getFilename()); + Assert.assertNotNull(docInfos.getDocument()); + Assert.assertEquals("mchc_i_002.xml", docInfos.getFilename()); + + //get the question DOM's + List<ItemInfos> itemElements = proc.getItemList(docInfos); + Assert.assertNotNull(itemElements); + Assert.assertEquals(1, itemElements.size()); + + //process item + QuestionItem item = proc.processItem(itemElements.get(0)); + Assert.assertNotNull(item); + dbInstance.commitAndCloseSession(); + + //reload and check what is saved + QuestionItem reloadItem = questionItemDao.loadById(item.getKey()); + Assert.assertNotNull(reloadItem); + Assert.assertNotNull(reloadItem.getCreationDate()); + Assert.assertNotNull(reloadItem.getLastModified()); + Assert.assertEquals(QuestionStatus.draft, reloadItem.getQuestionStatus()); + Assert.assertEquals(QTIConstants.QTI_12_FORMAT, reloadItem.getFormat()); + //title + Assert.assertEquals("Standard Multiple Choice with Images Item", reloadItem.getTitle()); + //description -> qticomment + Assert.assertEquals("This is a multiple-choice example with image content. The rendering is a standard radio button style. No response processing is incorporated.", reloadItem.getDescription()); + //question type + Assert.assertEquals(QuestionType.SC, reloadItem.getQuestionType()); + } + + @Test + public void testImport_FIB() throws IOException, URISyntaxException { + URL itemUrl = QTIImportProcessorTest.class.getResource("fibi_i_001.xml"); + Assert.assertNotNull(itemUrl); + File itemFile = new File(itemUrl.toURI()); + + //get the document informations + QTIImportProcessor proc = new QTIImportProcessor(owner, itemFile.getName(), itemFile, questionItemDao); + List<QuestionItem> items = proc.process(); + Assert.assertNotNull(items); + Assert.assertEquals(1, items.size()); + dbInstance.commitAndCloseSession(); + + //reload and check what is saved + QuestionItem reloadItem = questionItemDao.loadById(items.get(0).getKey()); + Assert.assertNotNull(reloadItem); + Assert.assertNotNull(reloadItem.getCreationDate()); + Assert.assertNotNull(reloadItem.getLastModified()); + Assert.assertEquals(QuestionStatus.draft, reloadItem.getQuestionStatus()); + Assert.assertEquals(QTIConstants.QTI_12_FORMAT, reloadItem.getFormat()); + //title + Assert.assertEquals("Standard FIB numerical Item", reloadItem.getTitle()); + //description -> qticomment + Assert.assertEquals("This is a standard numerical fill-in-blank (integer) example. No response processing is incorporated.", reloadItem.getDescription()); + //question type + Assert.assertEquals(QuestionType.FIB, reloadItem.getQuestionType()); + } + + + + + + + + + + +} diff --git a/src/test/java/org/olat/ims/qti/qpool/fibi_i_001.xml b/src/test/java/org/olat/ims/qti/qpool/fibi_i_001.xml new file mode 100644 index 00000000000..57e8bea0866 --- /dev/null +++ b/src/test/java/org/olat/ims/qti/qpool/fibi_i_001.xml @@ -0,0 +1 @@ +<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <!DOCTYPE questestinterop SYSTEM "ims_qtiasiv1p2.dtd"> <!-- Author: Colin Smythe --> <!-- Date: 22nd January, 2002 --> <!-- Version 1.2 Compliant Example: BasicExample016a --> <!-- Basic Example 16a --> <questestinterop> <qticomment>This is a standard numerical fill-in-blank (integer) example. No response processing is incorporated.</qticomment> <item title = "Standard FIB numerical Item" ident = "IMS_V01_I_fibi_i_001"> <presentation label = "BasicExample016a"> <flow> <response_num ident = "NUM02" rcardinality = "Single" rtiming = "No"> <render_fib fibtype = "Integer" prompt = "Asterisk" maxchars = "3"> <material> <mattext charset = "ascii/us">What is 13 x 13 ?</mattext> </material> <response_label ident = "A"/> </render_fib> </response_num> </flow> </presentation> </item> </questestinterop> \ No newline at end of file diff --git a/src/test/java/org/olat/ims/qti/qpool/mchc_i_002.xml b/src/test/java/org/olat/ims/qti/qpool/mchc_i_002.xml new file mode 100644 index 00000000000..34da240bd69 --- /dev/null +++ b/src/test/java/org/olat/ims/qti/qpool/mchc_i_002.xml @@ -0,0 +1 @@ +<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <!DOCTYPE questestinterop SYSTEM "ims_qtiasiv1p2.dtd"> <!-- Author: Colin Smythe --> <!-- Date: 22nd January, 2002 --> <!-- Version 1.2 Compliant Example: BasicExample003a --> <questestinterop> <qticomment>This is a multiple-choice example with image content. The rendering is a standard radio button style. No response processing is incorporated.</qticomment> <item title = "Standard Multiple Choice with Images Item" ident = "IMS_V01_I_mchc_i_002"> <presentation label = "BasicExample003a"> <flow> <material> <mattext>Which symbol is the 'Stop' sign ?</mattext> </material> <response_lid ident = "MC02" rcardinality = "Single" rtiming = "No"> <render_choice shuffle = "Yes"> <flow_label> <response_label ident = "A"> <material> <matimage imagtype = "image/gif" uri = "image1.gif"/> </material> </response_label> <response_label ident = "B"> <material> <matimage imagtype = "image/gif" uri = "image2.gif"/> </material> </response_label> <response_label ident = "C"> <material> <matimage imagtype = "image/gif" uri = "image3.gif"/> </material> </response_label> <response_label ident = "D"> <material> <matimage imagtype = "image/gif" uri = "image4.gif"/> </material> </response_label> </flow_label> </render_choice> </response_lid> </flow> </presentation> </item> </questestinterop> \ No newline at end of file diff --git a/src/test/java/org/olat/modules/ims/qti/fileresource/FileResourceValidatorTest.java b/src/test/java/org/olat/modules/ims/qti/fileresource/FileResourceValidatorTest.java index 9e2585c8dca..5fa3cb9ac8e 100644 --- a/src/test/java/org/olat/modules/ims/qti/fileresource/FileResourceValidatorTest.java +++ b/src/test/java/org/olat/modules/ims/qti/fileresource/FileResourceValidatorTest.java @@ -29,7 +29,7 @@ import java.net.URL; import junit.framework.Assert; import org.junit.Test; -import org.olat.ims.qti.fileresource.ItemFileResourceValidator; +import org.olat.ims.qti.qpool.ItemFileResourceValidator; /** * diff --git a/src/test/java/org/olat/modules/qpool/manager/CollectionDAOTest.java b/src/test/java/org/olat/modules/qpool/manager/CollectionDAOTest.java index fa4aacff37e..ed045790712 100644 --- a/src/test/java/org/olat/modules/qpool/manager/CollectionDAOTest.java +++ b/src/test/java/org/olat/modules/qpool/manager/CollectionDAOTest.java @@ -31,6 +31,7 @@ import org.olat.core.id.Identity; import org.olat.ims.qti.QTIConstants; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItemCollection; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionType; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; @@ -81,11 +82,11 @@ public class CollectionDAOTest extends OlatTestCase { public void addItemToCollectionById() { Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Coll-Onwer-2-" + UUID.randomUUID().toString()); QuestionItemCollection coll = collectionDao.createCollection("NGC collection 2", id); - QuestionItem item = questionDao.create(null, "NGC 89", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, QuestionType.FIB); + QuestionItem item = questionDao.createAndPersist(null, "NGC 89", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, null, QuestionType.FIB); dbInstance.commitAndCloseSession(); //add the item to the collection - collectionDao.addItemToCollection(item, coll); + collectionDao.addItemToCollection(item.getKey(), coll); dbInstance.commit();//check if it's alright } @@ -94,14 +95,14 @@ public class CollectionDAOTest extends OlatTestCase { //create a collection with 2 items Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Coll-Onwer-3-" + UUID.randomUUID().toString()); QuestionItemCollection coll = collectionDao.createCollection("NGC collection 3", id); - QuestionItem item1 = questionDao.create(null, "NGC 92", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, QuestionType.FIB); - QuestionItem item2 = questionDao.create(null, "NGC 97", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, QuestionType.FIB); - collectionDao.addItemToCollection(item1, coll); - collectionDao.addItemToCollection(item2, coll); + QuestionItem item1 = questionDao.createAndPersist(null, "NGC 92", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, null, QuestionType.FIB); + QuestionItem item2 = questionDao.createAndPersist(null, "NGC 97", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, null, QuestionType.FIB); + collectionDao.addItemToCollection(item1.getKey(), coll); + collectionDao.addItemToCollection(item2.getKey(), coll); dbInstance.commit();//check if it's alright //load the items of the collection - List<QuestionItem> items = collectionDao.getItemsOfCollection(coll, null, 0, -1); + List<QuestionItemShort> items = collectionDao.getItemsOfCollection(coll, null, 0, -1); Assert.assertNotNull(items); Assert.assertEquals(2, items.size()); Assert.assertTrue(items.contains(item1)); @@ -111,7 +112,7 @@ public class CollectionDAOTest extends OlatTestCase { Assert.assertEquals(2, numOfItems); //load limit sub set - List<QuestionItem> limitedItems = collectionDao.getItemsOfCollection(coll, Collections.singletonList(item1.getKey()), 0, -1); + List<QuestionItemShort> limitedItems = collectionDao.getItemsOfCollection(coll, Collections.singletonList(item1.getKey()), 0, -1); Assert.assertNotNull(limitedItems); Assert.assertEquals(1, limitedItems.size()); Assert.assertTrue(limitedItems.contains(item1)); @@ -122,10 +123,10 @@ public class CollectionDAOTest extends OlatTestCase { //create a collection with 2 items Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Coll-Onwer-4-" + UUID.randomUUID().toString()); QuestionItemCollection coll = collectionDao.createCollection("NGC collection 4", id); - QuestionItem item1 = questionDao.create(null, "NGC 99", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, QuestionType.FIB); - QuestionItem item2 = questionDao.create(null, "NGC 101", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, QuestionType.FIB); - collectionDao.addItemToCollection(item1, coll); - collectionDao.addItemToCollection(item2, coll); + QuestionItem item1 = questionDao.createAndPersist(null, "NGC 99", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, null, QuestionType.FIB); + QuestionItem item2 = questionDao.createAndPersist(null, "NGC 101", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, null, QuestionType.FIB); + collectionDao.addItemToCollection(item1.getKey(), coll); + collectionDao.addItemToCollection(item2.getKey(), coll); dbInstance.commit();//check if it's alright //load the items of the collection diff --git a/src/test/java/org/olat/modules/qpool/manager/PoolDAOTest.java b/src/test/java/org/olat/modules/qpool/manager/PoolDAOTest.java index 7096f5d626c..becb4bf5004 100644 --- a/src/test/java/org/olat/modules/qpool/manager/PoolDAOTest.java +++ b/src/test/java/org/olat/modules/qpool/manager/PoolDAOTest.java @@ -19,6 +19,7 @@ */ package org.olat.modules.qpool.manager; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.UUID; @@ -30,10 +31,12 @@ import org.olat.core.commons.persistence.DB; import org.olat.ims.qti.QTIConstants; import org.olat.modules.qpool.Pool; import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionType; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; + /** * * Initial date: 21.01.2013<br> @@ -93,7 +96,7 @@ public class PoolDAOTest extends OlatTestCase { String name = "NGC-" + UUID.randomUUID().toString(); Pool pool = poolDao.createPool(name); Assert.assertNotNull(pool); - QuestionItem item = questionItemDao.create(null, "Galaxy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionItemDao.createAndPersist(null, "Galaxy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); Assert.assertNotNull(item); dbInstance.commitAndCloseSession(); @@ -107,12 +110,12 @@ public class PoolDAOTest extends OlatTestCase { //create a pool String name = "NGC-" + UUID.randomUUID().toString(); Pool pool = poolDao.createPool(name); - QuestionItem item = questionItemDao.create(null, "Galaxy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionItemDao.createAndPersist(null, "Galaxy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); poolDao.addItemToPool(item, pool); dbInstance.commitAndCloseSession(); //retrieve - List<QuestionItem> items = poolDao.getItemsOfPool(pool, null, 0 , -1); + List<QuestionItemShort> items = poolDao.getItemsOfPool(pool, null, 0 , -1); Assert.assertNotNull(items); Assert.assertEquals(1, items.size()); Assert.assertTrue(items.contains(item)); @@ -127,7 +130,7 @@ public class PoolDAOTest extends OlatTestCase { String name = "NGC-" + UUID.randomUUID().toString(); Pool pool1 = poolDao.createPool(name); Pool pool2 = poolDao.createPool(name + "-b"); - QuestionItem item = questionItemDao.create(null, "Galaxy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionItemDao.createAndPersist(null, "Galaxy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); poolDao.addItemToPool(item, pool1); poolDao.addItemToPool(item, pool2); dbInstance.commitAndCloseSession(); @@ -145,19 +148,20 @@ public class PoolDAOTest extends OlatTestCase { //create a pool with an item String name = "NGC-" + UUID.randomUUID().toString(); Pool pool = poolDao.createPool(name); - QuestionItem item = questionItemDao.create(null, "Galaxy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionItemDao.createAndPersist(null, "Galaxy", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); poolDao.addItemToPool(item, pool); dbInstance.commitAndCloseSession(); //check the pool and remove the items - List<QuestionItem> items = poolDao.getItemsOfPool(pool, null, 0 , -1); + List<QuestionItemShort> items = poolDao.getItemsOfPool(pool, null, 0 , -1); Assert.assertEquals(1, items.size()); - int count = poolDao.deleteFromPools(items); + List<QuestionItemShort> toDelete = Collections.singletonList(items.get(0)); + int count = poolDao.deleteFromPools(toDelete); Assert.assertEquals(1, count); dbInstance.commitAndCloseSession(); //check if the pool is empty - List<QuestionItem> emptyItems = poolDao.getItemsOfPool(pool, null, 0 , -1); + List<QuestionItemShort> emptyItems = poolDao.getItemsOfPool(pool, null, 0 , -1); Assert.assertTrue(emptyItems.isEmpty()); } diff --git a/src/test/java/org/olat/modules/qpool/manager/QuestionDAOTest.java b/src/test/java/org/olat/modules/qpool/manager/QuestionDAOTest.java index 2a0d2bedaab..75992310847 100644 --- a/src/test/java/org/olat/modules/qpool/manager/QuestionDAOTest.java +++ b/src/test/java/org/olat/modules/qpool/manager/QuestionDAOTest.java @@ -35,6 +35,7 @@ import org.olat.group.BusinessGroup; import org.olat.group.manager.BusinessGroupDAO; import org.olat.ims.qti.QTIConstants; import org.olat.modules.qpool.QuestionItem; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionType; import org.olat.resource.OLATResource; import org.olat.test.JunitTestHelper; @@ -60,7 +61,7 @@ public class QuestionDAOTest extends OlatTestCase { @Test public void createQuestion() { - QuestionItem item = questionDao.create(null, "Stars", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.FIB); + QuestionItem item = questionDao.createAndPersist(null, "Stars", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.FIB); Assert.assertNotNull(item); Assert.assertNotNull(item.getKey()); Assert.assertNotNull(item.getIdentifier()); @@ -75,7 +76,7 @@ public class QuestionDAOTest extends OlatTestCase { @Test public void createQuestion_withOwner() { Identity id = JunitTestHelper.createAndPersistIdentityAsUser("QOwn-1-" + UUID.randomUUID().toString()); - QuestionItem item = questionDao.create(id, "My fav. stars", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.FIB); + QuestionItem item = questionDao.createAndPersist(id, "My fav. stars", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.FIB); Assert.assertNotNull(item); Assert.assertNotNull(item.getKey()); Assert.assertNotNull(item.getCreationDate()); @@ -90,22 +91,22 @@ public class QuestionDAOTest extends OlatTestCase { public void getItems_byAuthor() { //create an author with 2 items Identity id = JunitTestHelper.createAndPersistIdentityAsUser("QOwn-2-" + UUID.randomUUID().toString()); - QuestionItem item1 = questionDao.create(id, "NGC 2171", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.FIB); - QuestionItem item2 = questionDao.create(id, "NGC 2172", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.FIB); + QuestionItem item1 = questionDao.createAndPersist(id, "NGC 2171", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.FIB); + QuestionItem item2 = questionDao.createAndPersist(id, "NGC 2172", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.FIB); dbInstance.commitAndCloseSession(); //count the items of the author int numOfItems = questionDao.countItems(id); Assert.assertEquals(2, numOfItems); //retrieve the items of the author - List<QuestionItem> items = questionDao.getItems(id, null, 0, -1); + List<QuestionItemShort> items = questionDao.getItems(id, null, 0, -1); Assert.assertNotNull(items); Assert.assertEquals(2, items.size()); Assert.assertTrue(items.contains(item1)); Assert.assertTrue(items.contains(item2)); //limit the list - List<QuestionItem> limitedItems = questionDao.getItems(id, Collections.singletonList(item1.getKey()), 0, -1); + List<QuestionItemShort> limitedItems = questionDao.getItems(id, Collections.singletonList(item1.getKey()), 0, -1); Assert.assertNotNull(limitedItems); Assert.assertEquals(1, limitedItems.size()); Assert.assertTrue(limitedItems.contains(item1)); @@ -113,7 +114,7 @@ public class QuestionDAOTest extends OlatTestCase { @Test public void getNumOfQuestions() { - QuestionItem item = questionDao.create(null, "NGC 1277", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionDao.createAndPersist(null, "NGC 1277", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); Assert.assertNotNull(item); dbInstance.commitAndCloseSession(); @@ -125,14 +126,14 @@ public class QuestionDAOTest extends OlatTestCase { @Test public void getFavoritItems() { Identity id = JunitTestHelper.createAndPersistIdentityAsUser("fav-item-" + UUID.randomUUID().toString()); - QuestionItem item1 = questionDao.create(id, "NGC 55", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); - QuestionItem item2 = questionDao.create(id, "NGC 253", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); - QuestionItem item3 = questionDao.create(id, "NGC 292", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item1 = questionDao.createAndPersist(id, "NGC 55", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); + QuestionItem item2 = questionDao.createAndPersist(id, "NGC 253", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); + QuestionItem item3 = questionDao.createAndPersist(id, "NGC 292", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); markManager.setMark(item1, id, null, "[QuestionItem:" + item1 + "]"); markManager.setMark(item2, id, null, "[QuestionItem:" + item2 + "]"); dbInstance.commitAndCloseSession(); - List<QuestionItem> favorits = questionDao.getFavoritItems(id, null, 0, -1); + List<QuestionItemShort> favorits = questionDao.getFavoritItems(id, null, 0, -1); Assert.assertNotNull(favorits); Assert.assertEquals(2, favorits.size()); Assert.assertTrue(favorits.contains(item1)); @@ -140,7 +141,7 @@ public class QuestionDAOTest extends OlatTestCase { Assert.assertFalse(favorits.contains(item3)); //limit to the first favorit - List<QuestionItem> limitedFavorits = questionDao.getFavoritItems(id, Collections.singletonList(item1.getKey()), 0, -1); + List<QuestionItemShort> limitedFavorits = questionDao.getFavoritItems(id, Collections.singletonList(item1.getKey()), 0, -1); Assert.assertNotNull(limitedFavorits); Assert.assertEquals(1, limitedFavorits.size()); Assert.assertTrue(limitedFavorits.contains(item1)); @@ -149,9 +150,9 @@ public class QuestionDAOTest extends OlatTestCase { @Test public void getFavoritItemKeys() { Identity id = JunitTestHelper.createAndPersistIdentityAsUser("fav-item-" + UUID.randomUUID().toString()); - QuestionItem item1 = questionDao.create(id, "NGC 331", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); - QuestionItem item2 = questionDao.create(id, "NGC 332", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); - QuestionItem item3 = questionDao.create(id, "NGC 333", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item1 = questionDao.createAndPersist(id, "NGC 331", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); + QuestionItem item2 = questionDao.createAndPersist(id, "NGC 332", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); + QuestionItem item3 = questionDao.createAndPersist(id, "NGC 333", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); markManager.setMark(item1, id, null, "[QuestionItem:" + item1 + "]"); markManager.setMark(item2, id, null, "[QuestionItem:" + item2 + "]"); dbInstance.commitAndCloseSession(); @@ -168,8 +169,8 @@ public class QuestionDAOTest extends OlatTestCase { public void shareItems() { //create a group to share 2 items BusinessGroup group = businessGroupDao.createAndPersist(null, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); - QuestionItem item1 = questionDao.create(null, "Share-Item-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); - QuestionItem item2 = questionDao.create(null, "Share-Item-2", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item1 = questionDao.createAndPersist(null, "Share-Item-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); + QuestionItem item2 = questionDao.createAndPersist(null, "Share-Item-2", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); dbInstance.commit(); //share them @@ -177,14 +178,14 @@ public class QuestionDAOTest extends OlatTestCase { questionDao.share(item2, group.getResource()); //retrieve them - List<QuestionItem> sharedItems = questionDao.getSharedItemByResource(group.getResource(), null, 0, -1); + List<QuestionItemShort> sharedItems = questionDao.getSharedItemByResource(group.getResource(), null, 0, -1); Assert.assertNotNull(sharedItems); Assert.assertEquals(2, sharedItems.size()); Assert.assertTrue(sharedItems.contains(item1)); Assert.assertTrue(sharedItems.contains(item2)); //retrieve limited sub set - List<QuestionItem> limitedSharedItems = questionDao.getSharedItemByResource(group.getResource(), Collections.singletonList(item1.getKey()), 0, -1); + List<QuestionItemShort> limitedSharedItems = questionDao.getSharedItemByResource(group.getResource(), Collections.singletonList(item1.getKey()), 0, -1); Assert.assertNotNull(limitedSharedItems); Assert.assertEquals(1, limitedSharedItems.size()); Assert.assertTrue(limitedSharedItems.contains(item1)); @@ -194,9 +195,9 @@ public class QuestionDAOTest extends OlatTestCase { public void shareItems_countSharedItemByResource() { //create a group to share 2 items BusinessGroup group = businessGroupDao.createAndPersist(null, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); - QuestionItem item1 = questionDao.create(null, "Count-shared-Item-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); - QuestionItem item2 = questionDao.create(null, "Count-shared-Item-2", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); - QuestionItem item3 = questionDao.create(null, "Count-shared-Item-3", QTIConstants.QTI_12_FORMAT, Locale.FRENCH.getLanguage(), null, null, QuestionType.FIB); + QuestionItem item1 = questionDao.createAndPersist(null, "Count-shared-Item-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); + QuestionItem item2 = questionDao.createAndPersist(null, "Count-shared-Item-2", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); + QuestionItem item3 = questionDao.createAndPersist(null, "Count-shared-Item-3", QTIConstants.QTI_12_FORMAT, Locale.FRENCH.getLanguage(), null, null, null, QuestionType.FIB); dbInstance.commit(); //share them @@ -215,21 +216,21 @@ public class QuestionDAOTest extends OlatTestCase { //create a group to share 2 items BusinessGroup group1 = businessGroupDao.createAndPersist(null, "gdao-1", "gdao-desc", -1, -1, false, false, false, false, false); BusinessGroup group2 = businessGroupDao.createAndPersist(null, "gdao-2", "gdao-desc", -1, -1, false, false, false, false, false); - QuestionItem item = questionDao.create(null, "Share-Item-3", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionDao.createAndPersist(null, "Share-Item-3", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); dbInstance.commit(); //share them List<OLATResource> resources = new ArrayList<OLATResource>(); resources.add(group1.getResource()); resources.add(group2.getResource()); - questionDao.share(item, resources); + questionDao.share(item.getKey(), resources); //retrieve them - List<QuestionItem> sharedItems1 = questionDao.getSharedItemByResource(group1.getResource(), null, 0, -1); + List<QuestionItemShort> sharedItems1 = questionDao.getSharedItemByResource(group1.getResource(), null, 0, -1); Assert.assertNotNull(sharedItems1); Assert.assertEquals(1, sharedItems1.size()); Assert.assertTrue(sharedItems1.contains(item)); - List<QuestionItem> sharedItems2 = questionDao.getSharedItemByResource(group2.getResource(), null, 0, -1); + List<QuestionItemShort> sharedItems2 = questionDao.getSharedItemByResource(group2.getResource(), null, 0, -1); Assert.assertNotNull(sharedItems2); Assert.assertEquals(1, sharedItems2.size()); Assert.assertTrue(sharedItems2.contains(item)); @@ -239,7 +240,7 @@ public class QuestionDAOTest extends OlatTestCase { public void shareItems_avoidDuplicates() { //create a group to share 2 items BusinessGroup group = businessGroupDao.createAndPersist(null, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); - QuestionItem item = questionDao.create(null, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionDao.createAndPersist(null, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); dbInstance.commit(); //share them @@ -248,7 +249,7 @@ public class QuestionDAOTest extends OlatTestCase { questionDao.share(item, group.getResource()); //retrieve them - List<QuestionItem> sharedItems = questionDao.getSharedItemByResource(group.getResource(), null, 0, -1); + List<QuestionItemShort> sharedItems = questionDao.getSharedItemByResource(group.getResource(), null, 0, -1); Assert.assertNotNull(sharedItems); Assert.assertEquals(1, sharedItems.size()); Assert.assertTrue(sharedItems.contains(item)); @@ -259,7 +260,7 @@ public class QuestionDAOTest extends OlatTestCase { //create a group to share 2 items Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-item-" + UUID.randomUUID().toString()); BusinessGroup group = businessGroupDao.createAndPersist(id, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); - QuestionItem item = questionDao.create(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); dbInstance.commit(); //share them @@ -280,7 +281,7 @@ public class QuestionDAOTest extends OlatTestCase { Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-item-" + UUID.randomUUID().toString()); BusinessGroup group1 = businessGroupDao.createAndPersist(id, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); BusinessGroup group2 = businessGroupDao.createAndPersist(id, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); - QuestionItem item = questionDao.create(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionDao.createAndPersist(id, "Share-Item-Dup-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); dbInstance.commit(); //share them @@ -301,16 +302,17 @@ public class QuestionDAOTest extends OlatTestCase { //create a group to share 2 items Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-rm-" + UUID.randomUUID().toString()); BusinessGroup group = businessGroupDao.createAndPersist(id, "gdrm", "gdrm-desc", -1, -1, false, false, false, false, false); - QuestionItem item = questionDao.create(id, "Share-item-rm-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item = questionDao.createAndPersist(id, "Share-item-rm-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); dbInstance.commit(); //share them questionDao.share(item, group.getResource()); //retrieve them as a check - List<QuestionItem> shared = questionDao.getSharedItemByResource(group.getResource(), null, 0, -1); + List<QuestionItemShort> shared = questionDao.getSharedItemByResource(group.getResource(), null, 0, -1); Assert.assertEquals(1, shared.size()); //and remove the items - int count = questionDao.deleteFromShares(shared); + List<QuestionItemShort> toDelete = Collections.singletonList((QuestionItemShort)shared.get(0)); + int count = questionDao.deleteFromShares(toDelete); Assert.assertEquals(1, count); dbInstance.commit();//make sure that changes are committed } diff --git a/src/test/java/org/olat/modules/qpool/manager/QuestionPoolServiceTest.java b/src/test/java/org/olat/modules/qpool/manager/QuestionPoolServiceTest.java index 636f79c5edd..397b57e43ad 100644 --- a/src/test/java/org/olat/modules/qpool/manager/QuestionPoolServiceTest.java +++ b/src/test/java/org/olat/modules/qpool/manager/QuestionPoolServiceTest.java @@ -41,6 +41,7 @@ import org.olat.group.manager.BusinessGroupDAO; import org.olat.ims.qti.QTIConstants; import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItemCollection; +import org.olat.modules.qpool.QuestionItemShort; import org.olat.modules.qpool.QuestionPoolService; import org.olat.modules.qpool.QuestionType; import org.olat.test.JunitTestHelper; @@ -69,18 +70,18 @@ public class QuestionPoolServiceTest extends OlatTestCase { //create a group to share 2 items Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Share-rm-" + UUID.randomUUID().toString()); BusinessGroup group = businessGroupDao.createAndPersist(id, "gdrm", "gdrm-desc", -1, -1, false, false, false, false, false); - QuestionItem item1 = questionDao.create(id, "Share-item-rm-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); - QuestionItem item2 = questionDao.create(id, "Share-item-rm-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, QuestionType.MC); + QuestionItem item1 = questionDao.createAndPersist(id, "Share-item-rm-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); + QuestionItem item2 = questionDao.createAndPersist(id, "Share-item-rm-1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, QuestionType.MC); dbInstance.commit(); //share them questionDao.share(item1, group.getResource()); dbInstance.commitAndCloseSession(); //delete the items - List<QuestionItem> shared = new ArrayList<QuestionItem>(); - shared.add(item1); - shared.add(item2); - qpoolService.deleteItems(shared); + List<QuestionItemShort> toDelete = new ArrayList<QuestionItemShort>(); + toDelete.add(item1); + toDelete.add(item2); + qpoolService.deleteItems(toDelete); dbInstance.commit();//make sure that changes are committed //check if they exists @@ -94,12 +95,12 @@ public class QuestionPoolServiceTest extends OlatTestCase { public void createCollection() { //create an user with 2 items Identity id = JunitTestHelper.createAndPersistIdentityAsUser("Coll-Owner-3-" + UUID.randomUUID().toString()); - QuestionItem item1 = questionDao.create(id, "NGC 92", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, QuestionType.FIB); - QuestionItem item2 = questionDao.create(id, "NGC 97", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, QuestionType.FIB); + QuestionItem item1 = questionDao.createAndPersist(id, "NGC 92", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, null, QuestionType.FIB); + QuestionItem item2 = questionDao.createAndPersist(id, "NGC 97", QTIConstants.QTI_12_FORMAT, Locale.GERMAN.getLanguage(), null, null, null, QuestionType.FIB); dbInstance.commit(); //load the items of the collection - List<QuestionItem> items = new ArrayList<QuestionItem>(); + List<QuestionItemShort> items = new ArrayList<QuestionItemShort>(); items.add(item1); items.add(item2); QuestionItemCollection newColl = qpoolService.createCollection(id, "My private collection", items); @@ -110,7 +111,7 @@ public class QuestionPoolServiceTest extends OlatTestCase { //retrieve the list of items in the collection int numOfItemsInCollection = qpoolService.countItemsOfCollection(newColl); Assert.assertEquals(2, numOfItemsInCollection); - ResultInfos<QuestionItem> itemsOfCollection = qpoolService.getItemsOfCollection(newColl, null, 0, -1); + ResultInfos<QuestionItemShort> itemsOfCollection = qpoolService.getItemsOfCollection(newColl, null, 0, -1); Assert.assertNotNull(itemsOfCollection); Assert.assertEquals(2, itemsOfCollection.getObjects().size()); Assert.assertTrue(itemsOfCollection.getObjects().contains(item1)); @@ -118,17 +119,26 @@ public class QuestionPoolServiceTest extends OlatTestCase { } @Test - public void importItem_qti12xml() throws IOException, URISyntaxException { + public void importItem_qti12_item() throws IOException, URISyntaxException { Identity owner = JunitTestHelper.createAndPersistIdentityAsUser("Imp-Owner-1-" + UUID.randomUUID().toString()); dbInstance.commit(); URL itemUrl = QuestionPoolServiceTest.class.getResource("mchc_i_001.xml"); assertNotNull(itemUrl); File itemFile = new File(itemUrl.toURI()); - - - qpoolService.importItem(owner, "mchc_i_001.xml", itemFile); - - + + qpoolService.importItems(owner, "mchc_i_001.xml", itemFile); } -} + @Test + public void importItem_qti12_assessment() throws IOException, URISyntaxException { + Identity owner = JunitTestHelper.createAndPersistIdentityAsUser("Imp-Owner-2-" + UUID.randomUUID().toString()); + dbInstance.commit(); + URL itemUrl = QuestionPoolServiceTest.class.getResource("mchc_asmimr_101.xml"); + assertNotNull(itemUrl); + File itemFile = new File(itemUrl.toURI()); + + qpoolService.importItems(owner, "mchc_asmimr_101.xml", itemFile); + } + + +} \ No newline at end of file diff --git a/src/test/java/org/olat/modules/qpool/manager/mchc_asmimr_101.xml b/src/test/java/org/olat/modules/qpool/manager/mchc_asmimr_101.xml new file mode 100644 index 00000000000..11f8e66925e --- /dev/null +++ b/src/test/java/org/olat/modules/qpool/manager/mchc_asmimr_101.xml @@ -0,0 +1 @@ +<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <!DOCTYPE questestinterop SYSTEM "ims_qtiasiv1p2.dtd"> <!-- Date: 22nd January, 2002 --> <!-- Version 1.2 Compliant Example: AdvExampleA01 --> <!-- Advanced Example with A(1)S(1)I(2)S(1)I(1) --> <questestinterop> <assessment title = "European Geography" ident = "A01"> <qticomment>A Complex Assessment example.</qticomment> <objectives view = "Candidate"> <flow_mat> <material> <mattext>To test your knowledge of European geography.</mattext> </material> </flow_mat> </objectives> <objectives view = "Assessor"> <flow_mat> <material> <mattext>Tests the candidate's knowledge of European geography.</mattext> </material> </flow_mat> </objectives> <outcomes_processing> <qticomment>Processing of the final accumulated assessment.</qticomment> <outcomes> <decvar/> </outcomes> <outcomes_feedback_test> <test_variable> <variable_test testoperator = "LTE">9</variable_test> </test_variable> <displayfeedback feedbacktype = "Response" linkrefid = "A01_FDB01"/> </outcomes_feedback_test> <outcomes_feedback_test> <test_variable> <variable_test testoperator = "GTE">10</variable_test> </test_variable> <displayfeedback feedbacktype = "Response" linkrefid = "A01_FDB02"/> </outcomes_feedback_test> </outcomes_processing> <assessfeedback title = "Failed" ident = "A01_FDB01"> <flow_mat> <material> <mattext>You failed the test.</mattext> </material> </flow_mat> </assessfeedback> <assessfeedback title = "Passed" ident = "A01_FDB02"> <flow_mat> <material> <mattext>You passed the test.</mattext> </material> </flow_mat> </assessfeedback> <section title = "European Capitals" ident = "S01"> <objectives view = "Candidate"> <flow_mat> <material> <mattext>To assess your knowledge of the capital cities in Europe.</mattext> </material> </flow_mat> </objectives> <objectives view = "Tutor"> <flow_mat> <material> <mattext>To ensure that the student knows the difference between the Capital cities of France, UK, Germany, Spain and Italy.</mattext> </material> </flow_mat> </objectives> <item title = "Capital of France" ident = "I01" maxattempts = "6"> <qticomment>This Item is the first example to be used in the QTI XML Binding Base Document.</qticomment> <itemmetadata/> <rubric view = "Candidate"> <flow_mat> <material> <mattext>Choose only one of the choices available.</mattext> </material> </flow_mat> </rubric> <presentation label = "Resp001"> <flow> <material> <mattext>What is the Capital of France ?</mattext> </material> <response_lid ident = "LID01"> <render_choice shuffle = "Yes"> <response_label ident = "LID01_A"> <flow_mat> <material> <mattext>London</mattext> </material> </flow_mat> </response_label> <response_label ident = "LID01_B"> <flow_mat> <material> <mattext>Paris</mattext> </material> </flow_mat> </response_label> <response_label ident = "LID01_C"> <flow_mat> <material> <mattext>Washington</mattext> </material> </flow_mat> </response_label> <response_label ident = "LID01_D" rshuffle = "No"> <flow_mat> <material> <mattext>Berlin</mattext> </material> </flow_mat> </response_label> </render_choice> </response_lid> </flow> </presentation> <resprocessing> <qticomment/> <outcomes> <decvar vartype = "Integer" defaultval = "0"/> </outcomes> <respcondition> <qticomment>Scoring for the correct answer.</qticomment> <conditionvar> <varequal respident = "LID01">LID01_B</varequal> </conditionvar> <setvar action = "Set" varname = "SCORE">10</setvar> <displayfeedback feedbacktype = "Response" linkrefid = "I01_IFBK01"/> </respcondition> </resprocessing> <itemfeedback title = "Correct answer" ident = "I01_IFBK01"> <flow_mat> <material> <mattext>Correct answer.</mattext> </material> </flow_mat> </itemfeedback> <itemfeedback ident = "I01_IFBK02"> <solution> <solutionmaterial> <flow_mat> <material> <mattext>London is the Capital of England.</mattext> </material> </flow_mat> <flow_mat> <material> <mattext>Paris is the Capital of France.</mattext> </material> </flow_mat> <flow_mat> <material> <mattext>Washington is in the USA.</mattext> </material> </flow_mat> <flow_mat> <material> <mattext>Berlin is the Capital of Germany.</mattext> </material> </flow_mat> </solutionmaterial> </solution> </itemfeedback> <itemfeedback ident = "I01_IFBK03" view = "All"> <hint feedbackstyle = "Multilevel"> <hintmaterial> <flow_mat> <material> <mattext>One of the choices is not in Europe.</mattext> </material> </flow_mat> </hintmaterial> <hintmaterial> <flow_mat> <material> <mattext>Berlin is the Capital of Germany.</mattext> </material> </flow_mat> </hintmaterial> <hintmaterial> <flow_mat> <material> <mattext>The Eiffel tower can be found in the Capital of France.</mattext> </material> </flow_mat> </hintmaterial> </hint> </itemfeedback> </item> </section> <section title = "European Rivers" ident = "SO2"> <objectives view = "Candidate"> <flow_mat> <material> <mattext>To assess your knowledge of the rivers in Europe.</mattext> </material> </flow_mat> </objectives> <objectives view = "Assessor"> <flow_mat> <material> <mattext>Questions on rivers in Germany, Spain, Italy and France.</mattext> </material> </flow_mat> </objectives> <item title = "Rivers in France question" ident = "I02"> <rubric view = "Candidate"> <flow_mat> <material> <mattext>Choose all of the correct answers.</mattext> </material> </flow_mat> </rubric> <presentation label = "Resp002"> <flow> <material> <mattext>Which rivers are in France ?</mattext> </material> <response_lid ident = "LID02" rcardinality = "Multiple"> <render_choice shuffle = "Yes" minnumber = "1" maxnumber = "2"> <response_label ident = "LID02_A"> <flow_mat> <material> <mattext>Seine</mattext> </material> </flow_mat> </response_label> <response_label ident = "LID02_B"> <flow_mat> <material> <mattext>Thames</mattext> </material> </flow_mat> </response_label> <response_label ident = "LID02_C"> <flow_mat> <material> <mattext>Danube</mattext> </material> </flow_mat> </response_label> <response_label ident = "LID02_D"> <flow_mat> <material> <mattext>Loire</mattext> </material> </flow_mat> </response_label> </render_choice> </response_lid> </flow> </presentation> </item> <item title = "Rivers in Germany" ident = "I03"> <rubric view = "Candidate"> <flow_mat> <material> <mattext>Choose all of the correct answers.</mattext> </material> </flow_mat> </rubric> <presentation label = "Resp003"> <flow> <material> <matimage imagtype = "image/jpeg" x0 = "500" y0 = "500" height = "200" uri = "image02.jpg"/> </material> <flow> <material> <mattext>Which rivers are in Germany ?</mattext> </material> <response_lid ident = "LID03" rcardinality = "Multiple"> <render_hotspot> <response_label ident = "LID03_A" rarea = "Ellipse">10,10,2,2</response_label> <response_label ident = "LID03_B" rarea = "Ellipse">15,15,2,2</response_label> <response_label ident = "LID03_C" rarea = "Ellipse">30,30,2,2</response_label> <response_label ident = "LID03_D" rarea = "Ellipse">60,60,2,2</response_label> <response_label ident = "LID03_E" rarea = "Ellipse">70,70,2,2</response_label> </render_hotspot> </response_lid> </flow> </flow> </presentation> </item> </section> </assessment> </questestinterop> \ No newline at end of file diff --git a/src/test/java/org/olat/modules/qpool/manager/mchc_i_001.xml b/src/test/java/org/olat/modules/qpool/manager/mchc_i_001.xml index e865fa086bd..0835b713793 100644 --- a/src/test/java/org/olat/modules/qpool/manager/mchc_i_001.xml +++ b/src/test/java/org/olat/modules/qpool/manager/mchc_i_001.xml @@ -1 +1 @@ -<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <!-- Author: Colin Smythe --> <!-- Date: 22nd January --> <!-- Version 1.2 Compliant Example: BasicExample002a --> <questestinterop> <qticomment>This is a simple multiple choice example. The rendering is a standard radio button style. No response processing is incorporated.</qticomment> <item title = "Standard Multiple Choice Item" ident = "IMS_V01_I_mchc_i_001"> <presentation label = "BasicExample002a"> <flow> <material> <mattext>Which one of the listed standards committees is responsible for developing the token ring specification ?</mattext> </material> <response_lid ident = "MCa_01" rcardinality = "Single" rtiming = "No"> <render_choice shuffle = "Yes"> <flow_label> <response_label ident = "A"> <material> <mattext>IEEE 802.3</mattext> </material> </response_label> </flow_label> <flow_label> <response_label ident = "B"> <material> <mattext>IEEE 802.5</mattext> </material> </response_label> </flow_label> <flow_label> <response_label ident = "C"> <material> <mattext>IEEE 802.6</mattext> </material> </response_label> </flow_label> <flow_label> <response_label ident = "D"> <material> <mattext>IEEE 802.11</mattext> </material> </response_label> </flow_label> <flow_label> <response_label ident = "E" rshuffle = "No"> <material> <mattext>None of the above.</mattext> </material> </response_label> </flow_label> </render_choice> </response_lid> </flow> </presentation> </item> </questestinterop> \ No newline at end of file +<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <!DOCTYPE questestinterop SYSTEM "ims_qtiasiv1p2.dtd"> <!-- Author: Colin Smythe --> <!-- Date: 22nd January --> <!-- Version 1.2 Compliant Example: BasicExample002a --> <questestinterop> <qticomment>This is a simple multiple choice example. The rendering is a standard radio button style. No response processing is incorporated.</qticomment> <item title = "Standard Multiple Choice Item" ident = "IMS_V01_I_mchc_i_001"> <presentation label = "BasicExample002a"> <flow> <material> <mattext>Which one of the listed standards committees is responsible for developing the token ring specification ?</mattext> </material> <response_lid ident = "MCa_01" rcardinality = "Single" rtiming = "No"> <render_choice shuffle = "Yes"> <flow_label> <response_label ident = "A"> <material> <mattext>IEEE 802.3</mattext> </material> </response_label> </flow_label> <flow_label> <response_label ident = "B"> <material> <mattext>IEEE 802.5</mattext> </material> </response_label> </flow_label> <flow_label> <response_label ident = "C"> <material> <mattext>IEEE 802.6</mattext> </material> </response_label> </flow_label> <flow_label> <response_label ident = "D"> <material> <mattext>IEEE 802.11</mattext> </material> </response_label> </flow_label> <flow_label> <response_label ident = "E" rshuffle = "No"> <material> <mattext>None of the above.</mattext> </material> </response_label> </flow_label> </render_choice> </response_lid> </flow> </presentation> </item> </questestinterop> \ No newline at end of file -- GitLab