diff --git a/pom.xml b/pom.xml index 27650051f79df9160ad57a9e0a86dc5ae7caf934..3cce29adf56fe11a1057e34e732b742942715190 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <targetJdk>1.8</targetJdk> - <org.springframework.version>5.2.6.RELEASE</org.springframework.version> + <org.springframework.version>5.2.7.RELEASE</org.springframework.version> <org.hibernate.version>5.4.15.Final</org.hibernate.version> <apache.cxf>3.3.6</apache.cxf> <apache.pdfbox>2.0.19</apache.pdfbox> diff --git a/src/main/java/org/olat/core/commons/services/text/impl/nutch/NGramProfile.java b/src/main/java/org/olat/core/commons/services/text/impl/nutch/NGramProfile.java index cee9175bfc66c36a4183ccc3a2e3f555ebf524a4..a4e5e673bfa8d6c416dd830bead25810574a6df7 100644 --- a/src/main/java/org/olat/core/commons/services/text/impl/nutch/NGramProfile.java +++ b/src/main/java/org/olat/core/commons/services/text/impl/nutch/NGramProfile.java @@ -472,7 +472,7 @@ public class NGramProfile { f = new File(profilename + "." + FILE_EXTENSION); FileOutputStream fos = new FileOutputStream(f); newProfile.save(fos); - System.out.println("new profile " + profilename + "." + FILE_EXTENSION + " was created."); + //System.out.println("new profile " + profilename + "." + FILE_EXTENSION + " was created."); break; case SIMILARITY: @@ -486,7 +486,7 @@ public class NGramProfile { fis = new FileInputStream(f); NGramProfile newProfile2 = NGramProfile.create(filename2, fis, encoding); newProfile2.normalize(); - System.out.println("Similarity is " + newProfile.getSimilarity(newProfile2)); + //System.out.println("Similarity is " + newProfile.getSimilarity(newProfile2)); break; case SCORE: @@ -500,7 +500,7 @@ public class NGramProfile { DEFAULT_MIN_NGRAM_LENGTH, DEFAULT_MAX_NGRAM_LENGTH); compare.load(fis); - System.out.println("Score is " + compare.getSimilarity(newProfile)); + //System.out.println("Score is " + compare.getSimilarity(newProfile)); break; } diff --git a/src/main/java/org/olat/core/gui/media/ServletUtil.java b/src/main/java/org/olat/core/gui/media/ServletUtil.java index d47bee277b1b54b9a0a8f4a7b8c35776aeeec532..06c3648272778d5aec29425c7e09c52b43161650 100644 --- a/src/main/java/org/olat/core/gui/media/ServletUtil.java +++ b/src/main/java/org/olat/core/gui/media/ServletUtil.java @@ -259,7 +259,6 @@ public class ServletUtil { try(InputStream istream = (resourceInputStream instanceof BufferedInputStream) ? resourceInputStream : new BufferedInputStream(resourceInputStream, bufferSize)) { stats.incrementConcurrentStreamCounter(); - Thread.sleep(5000); exception = copyRange(istream, ostream, range.start, range.end, bufferSize); } catch(IOException e) { handleIOException("Deliver range of data", e); diff --git a/src/main/java/org/olat/core/util/filter/impl/XMLValidEntityFilter.java b/src/main/java/org/olat/core/util/filter/impl/XMLValidEntityFilter.java index 6779846c33fb926875f692dad17e22c69a6904f1..b712f9e0c9985a8d9cf3c952b33179542e6757a1 100644 --- a/src/main/java/org/olat/core/util/filter/impl/XMLValidEntityFilter.java +++ b/src/main/java/org/olat/core/util/filter/impl/XMLValidEntityFilter.java @@ -80,7 +80,6 @@ public class XMLValidEntityFilter implements Filter { writer.append('&').append(entityContent).append(';'); } else if (entityValue < 0x20) { //skip them - System.out.println(); } else { writer.append('&').append(entityContent).append(';'); } diff --git a/src/main/java/org/olat/course/CoursefolderWebDAVMergeSource.java b/src/main/java/org/olat/course/CoursefolderWebDAVMergeSource.java index 2ddd8393db1d80163eda9937fc8c45a024830e8f..e9b5a99cc7fe770bf678978d0b4842850f6d437b 100644 --- a/src/main/java/org/olat/course/CoursefolderWebDAVMergeSource.java +++ b/src/main/java/org/olat/course/CoursefolderWebDAVMergeSource.java @@ -104,11 +104,6 @@ class CoursefolderWebDAVMergeSource extends WebDAVMergeSource { //add bookmarked courses if(webDAVModule.isEnableLearnersBookmarksCourse()) { List<RepositoryEntry> bookmarkedEntries = repositoryManager.getLearningResourcesAsBookmarkedMember(getIdentity(), identityEnv.getRoles(), "CourseModule", 0, -1); - for(RepositoryEntry bookmarkedEntry:bookmarkedEntries) { - System.out.println(bookmarkedEntry.getDisplayname()); - } - - appendCourses(bookmarkedEntries, containers, terms, noTermContainer, namingAndGrouping, false); } diff --git a/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeEditController.java b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeEditController.java index e24ed82a68fd41df6c4202d49fd2f101a6782e3a..db50cdba29e8357a02c067bc736136b9715ed21d 100644 --- a/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeEditController.java +++ b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeEditController.java @@ -393,7 +393,8 @@ public class AssessmentModeEditController extends FormBasicController { safeExamBrowserEl.addActionListener(FormEvent.ONCHANGE); safeExamBrowserEl.setEnabled(status != Status.end); String key = assessmentMode.getSafeExamBrowserKey(); - safeExamBrowserKeyEl = uifactory.addTextAreaElement("safeexamkey", "mode.safeexambrowser.key", 4096, 6, 60, false, false, key, formLayout); + safeExamBrowserKeyEl = uifactory.addTextAreaElement("safeexamkey", "mode.safeexambrowser.key", 16000, 6, 60, false, false, key, formLayout); + safeExamBrowserKeyEl.setMaxLength(16000); safeExamBrowserKeyEl.setVisible(assessmentMode.isSafeExamBrowser()); safeExamBrowserKeyEl.setEnabled(status != Status.end); String hint = assessmentMode.getSafeExamBrowserHint(); @@ -571,6 +572,9 @@ public class AssessmentModeEditController extends FormBasicController { if(!StringHelper.containsNonWhitespace(value)) { safeExamBrowserKeyEl.setErrorKey("form.legende.mandatory", null); allOk &= false; + } else if(value.length() > safeExamBrowserKeyEl.getMaxLength()) { + safeExamBrowserKeyEl.setErrorKey("form.error.toolong", new String[] { Integer.toString(safeExamBrowserKeyEl.getMaxLength()) } ); + allOk &= false; } } diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java index dbfd954edd7bf696c616b7715405f7dd309a3616..7931aa8acd2621a731405d33c3edd06db125372b 100644 --- a/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java +++ b/src/main/java/org/olat/course/member/wizard/ImportMemberOverviewIdentitiesController.java @@ -20,6 +20,7 @@ package org.olat.course.member.wizard; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -200,7 +201,7 @@ public class ImportMemberOverviewIdentitiesController extends StepFormBasicContr } } // make a lowercase copy of identList for processing username and email - List<String> identListLowercase = new ArrayList<>(identList.size()); + Collection<String> identListLowercase = new HashSet<>(identList.size()); for (String ident:identList) { identListLowercase.add(ident.toLowerCase()); } diff --git a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java index 2b5b709fc845462aa38b8983f6f58c5eab74f3c6..49e82d9ae1da79513deebef78b992a5d049e19a2 100644 --- a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java @@ -140,6 +140,8 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements QT private static final int CURRENT_CONFIG_VERSION = 2; + private transient RepositoryEntry cachedReferenceRepositoryEntry; + public IQTESTCourseNode() { this(null); } @@ -424,12 +426,27 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements QT sd.setActivateableViewIdentifier(pane); status.add(sd); } + + /** + * @return A cached instance of the reference repository entry. May be not suitable + * to insert an assessment entry. + */ + public RepositoryEntry getCachedReferencedRepositoryEntry() { + RepositoryEntry cachedEntry = cachedReferenceRepositoryEntry; + if(IQEditController.matchIQReference(cachedEntry, getModuleConfiguration())) { + return cachedEntry; + } + // The method updates the cache + return getReferencedRepositoryEntry(); + } @Override public RepositoryEntry getReferencedRepositoryEntry() { // ",false" because we do not want to be strict, but just indicate whether // the reference still exists or not - return IQEditController.getIQReference(getModuleConfiguration(), false); + RepositoryEntry entry = IQEditController.getIQReference(getModuleConfiguration(), false); + cachedReferenceRepositoryEntry = entry; + return entry; } @Override diff --git a/src/main/java/org/olat/course/nodes/cl/manager/CheckboxManagerImpl.java b/src/main/java/org/olat/course/nodes/cl/manager/CheckboxManagerImpl.java index 6f520f8e5ad2fcfb7e304adfbf0872d77c0f8ed3..ce06632f4b2efe698a1913fc18e40dff671d8af0 100644 --- a/src/main/java/org/olat/course/nodes/cl/manager/CheckboxManagerImpl.java +++ b/src/main/java/org/olat/course/nodes/cl/manager/CheckboxManagerImpl.java @@ -228,10 +228,6 @@ public class CheckboxManagerImpl implements CheckboxManager { } } } - - for(DBCheckbox dbCheckbox:uuids.values()) { - System.out.println("Remove them??? " + dbCheckbox.getCheckboxId()); - } } @Override diff --git a/src/main/java/org/olat/course/nodes/en/ENEditGroupAreaFormController.java b/src/main/java/org/olat/course/nodes/en/ENEditGroupAreaFormController.java index 7d6693993c3b66f199b6f56086c26cc06ebe3c31..40dbee1311b28275b17d36f8d4af7706253d815d 100644 --- a/src/main/java/org/olat/course/nodes/en/ENEditGroupAreaFormController.java +++ b/src/main/java/org/olat/course/nodes/en/ENEditGroupAreaFormController.java @@ -187,12 +187,13 @@ class ENEditGroupAreaFormController extends FormBasicController implements Gener List<EnrollmentRow> enrollmentRows = enrollmentManager.getEnrollments(getIdentity(), groupKeys, null, 256); Map<Long,EnrollmentRow> enrollmentMap = enrollmentRows.stream().collect(Collectors.toMap(EnrollmentRow::getKey, g -> g, (u, v) -> u)); - easyGroupTableRows = new ArrayList<ENEditGroupTableContentRow>(); + easyGroupTableRows = new ArrayList<>(); for (Long groupKey : groupKeys) { BusinessGroup group = groupMap.get(groupKey); - EnrollmentRow enrollment = enrollmentMap.get(groupKey); - - easyGroupTableRows.add(new ENEditGroupTableContentRow(group, enrollment)); + if(group != null) { + EnrollmentRow enrollment = enrollmentMap.get(groupKey); + easyGroupTableRows.add(new ENEditGroupTableContentRow(group, enrollment)); + } } easyGroupTableModel.setObjects(easyGroupTableRows); diff --git a/src/main/java/org/olat/course/nodes/iq/IQEditController.java b/src/main/java/org/olat/course/nodes/iq/IQEditController.java index 5ccffae1ab861376fe2d6b877b64a839dd6ede2e..f8377a910fc7330f5eb4b966731f7c94eb039959 100644 --- a/src/main/java/org/olat/course/nodes/iq/IQEditController.java +++ b/src/main/java/org/olat/course/nodes/iq/IQEditController.java @@ -380,6 +380,11 @@ public class IQEditController extends ActivateableTabbableDefaultController impl moduleConfiguration.set(CONFIG_KEY_REPOSITORY_SOFTKEY, re.getSoftkey()); } + public static boolean matchIQReference(RepositoryEntry re, ModuleConfiguration moduleConfiguration) { + String repoSoftkey = (String)moduleConfiguration.get(CONFIG_KEY_REPOSITORY_SOFTKEY); + return repoSoftkey != null && re != null && repoSoftkey.equals(re.getSoftkey()); + } + /** * Remove the reference to the repository entry. * diff --git a/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java b/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java index 620b487e457d42760ba9fdfc1069a445d66918d4..001840a25e0cd60aa70f167e7e45aae53da02a40 100644 --- a/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java +++ b/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java @@ -78,7 +78,7 @@ public class IQTESTAssessmentConfig implements AssessmentConfig { || IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) { maxScore = (Float) config.get(IQEditController.CONFIG_KEY_MAXSCORE); } else { - RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry(); + RepositoryEntry testEntry = courseNode.getCachedReferencedRepositoryEntry(); if (testEntry != null) { if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); @@ -107,7 +107,7 @@ public class IQTESTAssessmentConfig implements AssessmentConfig { || IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) { minScore = (Float) config.get(IQEditController.CONFIG_KEY_MINSCORE); } else { - RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry(); + RepositoryEntry testEntry = courseNode.getCachedReferencedRepositoryEntry(); if (testEntry != null) { if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); @@ -135,7 +135,7 @@ public class IQTESTAssessmentConfig implements AssessmentConfig { || IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) { mode = Mode.setByNode; } else { - RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry(); + RepositoryEntry testEntry = courseNode.getCachedReferencedRepositoryEntry(); if (testEntry != null) { if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); @@ -168,7 +168,7 @@ public class IQTESTAssessmentConfig implements AssessmentConfig { || IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) { cutValue = (Float) config.get(IQEditController.CONFIG_KEY_CUTVALUE); } else { - RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry(); + RepositoryEntry testEntry = courseNode.getCachedReferencedRepositoryEntry(); if (testEntry != null) { if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); diff --git a/src/main/java/org/olat/ims/qti21/QTI21Service.java b/src/main/java/org/olat/ims/qti21/QTI21Service.java index a5c6ba23d8de5405fddbd9ec81e176cfc23c65c2..2cdea6e1e4e9305ed61cbdbd1512157a4f1665f8 100644 --- a/src/main/java/org/olat/ims/qti21/QTI21Service.java +++ b/src/main/java/org/olat/ims/qti21/QTI21Service.java @@ -95,6 +95,17 @@ public interface QTI21Service { public URI createAssessmentTestUri(File resourceDirectory); + /** + * Ensure the assessment test is cached and not expired by + * the max. idle configuration. The goal is to maintain the + * object in cache despite it to be strong reference by the + * run controller. + * + * @param resourceDirectory The directory where is the package + */ + public void touchCachedResolveAssessmentTest(File resourceDirectory); + + /** * Load the assessmentTest based on the imsmanifest.xml found in the resource * directory. Return null if the imsmanifest.xml is not found. The assessmentTest diff --git a/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java b/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java index cb01875501c63407cfc2fb5d4f762ddeed1f3e24..01e479399abc4d5851361dc9a41f5bf6ecaf2aa3 100644 --- a/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java +++ b/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java @@ -329,6 +329,14 @@ public class QTI21ServiceImpl implements QTI21Service, UserDataDeletable, Initia return testSessionDao.hasActiveTestSession(testEntry); } + @Override + public void touchCachedResolveAssessmentTest(File resourceDirectory) { + URI assessmentObjectSystemId = createAssessmentTestUri(resourceDirectory); + if(assessmentObjectSystemId != null) { + assessmentTestsCache.get(resourceDirectory); + } + } + @Override public ResolvedAssessmentTest loadAndResolveAssessmentTest(File resourceDirectory, boolean replace, boolean debugInfo) { URI assessmentObjectSystemId = createAssessmentTestUri(resourceDirectory); @@ -416,7 +424,7 @@ public class QTI21ServiceImpl implements QTI21Service, UserDataDeletable, Initia public URI createAssessmentTestUri(final File resourceDirectory) { final String key = resourceDirectory.getAbsolutePath(); try { - return resourceToTestURI.computeIfAbsent(key, (directoryAbsolutPath) -> { + return resourceToTestURI.computeIfAbsent(key, directoryAbsolutPath -> { File manifestPath = new File(resourceDirectory, "imsmanifest.xml"); QTI21ContentPackage cp = new QTI21ContentPackage(manifestPath.toPath()); try { diff --git a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentHtmlBuilder.java b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentHtmlBuilder.java index 9be6d7e22710ff34a1235785f3d04674f11bc0de..287fa9f055f49b5227d31d883dcec645c17cfa4f 100644 --- a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentHtmlBuilder.java +++ b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentHtmlBuilder.java @@ -68,6 +68,7 @@ import uk.ac.ed.ph.jqtiplus.xmlutils.xslt.XsltSerializationOptions; public class AssessmentHtmlBuilder { private static final Logger log = Tracing.createLoggerFor(AssessmentHtmlBuilder.class); + private static final String SPACE = " "; private final QtiSerializer qtiSerializer; @@ -373,6 +374,8 @@ public class AssessmentHtmlBuilder { attributes.addAttribute("data-oo-movie", ooData); super.startElement("", "object", "object", attributes); + // ensure the tag is written <object> </object> and <object /> + super.characters(SPACE.toCharArray(), 0, SPACE.length()); super.endElement("", "object", "object"); } } diff --git a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java index 125c03a5f2d11cf4a609897845e3c3dde838fa6f..d0aea891e5c466122ca8bd123c3fe2e1e612811a 100644 --- a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java +++ b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java @@ -178,6 +178,7 @@ public class AssessmentTestDisplayController extends BasicController implements private DialogBoxController confirmSuspendDialog; private CandidateEvent lastEvent; + private Date touchTimestamp; private Date currentRequestTimestamp; private AssessmentTestSession candidateSession; private ResolvedAssessmentTest resolvedAssessmentTest; @@ -255,6 +256,7 @@ public class AssessmentTestDisplayController extends BasicController implements FileResourceManager frm = FileResourceManager.getInstance(); fUnzippedDirRoot = frm.unzipFileResource(testEntry.getOlatResource()); resolvedAssessmentTest = qtiService.loadAndResolveAssessmentTest(fUnzippedDirRoot, false, false); + touchTimestamp = ureq.getRequestTimestamp(); if(resolvedAssessmentTest == null || resolvedAssessmentTest.getRootNodeLookup().extractIfSuccessful() == null) { mainVC = createVelocityContainer("error"); } else { @@ -630,6 +632,28 @@ public class AssessmentTestDisplayController extends BasicController implements return sessionDeleted; } + /** + * This method maintains the assessment test in cache during + * a test session. This controller doesn't need the cache, the + * test is strong referenced but at the end of the test, score + * evaluation of the course, rendering of the assessment result + * can need the cache again. For very large tests, it can be a + * performance issue. + * + * @param ureq The user request + */ + private void touchResolvedAssessmentTest(UserRequest ureq) { + try { + Date timestamp = ureq.getRequestTimestamp(); + if(touchTimestamp == null || (timestamp.getTime() > touchTimestamp.getTime() + 300000l)) { + touchTimestamp = timestamp; + qtiService.touchCachedResolveAssessmentTest(fUnzippedDirRoot); + } + } catch (Exception e) { + logError("", e); + } + } + private boolean timeLimitBarrier(UserRequest ureq) { Long assessmentTestMaxTimeLimits = getAssessmentTestMaxTimeLimit(); if(assessmentTestMaxTimeLimits != null) { @@ -796,6 +820,8 @@ public class AssessmentTestDisplayController extends BasicController implements restartTest(ureq); break; } + + touchResolvedAssessmentTest(ureq); } private void restartTest(UserRequest ureq) { diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java index 8ce18b1a999d7865690b21ce437ea84134d1442c..cdbc7b2893eb26199a26d6a79a79ecfaa28b9fe7 100644 --- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java +++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java @@ -519,7 +519,6 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent renderTable(renderer, sb, component, resolvedAssessmentItem, itemSessionState, (Table)block, ubu, translator); break; case Object.QTI_CLASS_NAME: - System.out.println("1"); break; default: { renderStartHtmlTag(sb, component, resolvedAssessmentItem, block, null); diff --git a/src/main/java/org/olat/modules/adobeconnect/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/adobeconnect/ui/_i18n/LocalStrings_de.properties index 873c859a3f3178aff50ebd627af75421214e6be3..43c51cd1dec89a085c3e327777083cffcc0e9685 100644 --- a/src/main/java/org/olat/modules/adobeconnect/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/adobeconnect/ui/_i18n/LocalStrings_de.properties @@ -11,7 +11,7 @@ adobeconnect.module.enabled.for.groups=Gruppen adobeconnect.module.provider=Provider adobeconnect.title=Adobe Connect check=Serververbindung testen -confirm.delete.meeting=Wollen Sie wirklich den Meeting "{0}" l\u00F6schen? +confirm.delete.meeting=Wollen Sie wirklich das Meeting "{0}" l\u00F6schen? confirm.delete.meeting.title=Meeting "{0}" l\u00F6schen connection.failed=Login fehlgeschlagen. connection.successful=Login erfolgreich\! @@ -87,6 +87,6 @@ option.single.meeting=Verteilte Meetings option.single.meeting.single=Erstellt nur ein Meeting Raum pro Kursbaustein oder Gruppe option.single.meeting.perdate=Erstellt ein Meeting Raum pro Datum table.header.permanent=Dauernd -warning.no.access=Sie k\u00F6nnen noch nicht den Meeting beitreten. +warning.no.access=Sie k\u00F6nnen noch nicht dem Meeting beitreten. warning.no.meeting=Das Meeting wurde gel\u00F6scht. warning.not.registered.shared.documents=Nur die Personen die sich an den Meeting angemeldet haben d\u00FCrfen die Dokumenten ansehen. diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_de.properties index db52545f0ec195ab112ea9b467a23fcb490b8430..3133da49f45ec6f216c809bb3d0b0ead53893cc1 100644 --- a/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_de.properties @@ -166,7 +166,7 @@ view=Ansehen view.template=Raumvorlage "{0}" warning.at.least.one.meeting=Sie m\u00FCssen mindestens ein Meeting w\u00E4hlen. warning.meeting.started=Sie k\u00F6nnen ein gestartetes Meeting nicht mehr bearbeiten. -warning.no.access=Sie k\u00F6nnen noch nicht den Meeting beitreten. +warning.no.access=Sie k\u00F6nnen noch nicht dem Meeting beitreten. warning.no.meeting=Das Meeting wurde gel\u00F6scht. warning.template.in.use=Die Raumvorlage kann nicht gel\u00F6scht werden da sie nocht benutzt wird. L\u00F6schschen Sie zuerst die entsprechenden Online-Termine oder deaktivieren Sie die Raumvorlage. wizard.dates.title=Datum diff --git a/src/main/java/org/olat/modules/ceditor/ui/HTMLRawEditorController.java b/src/main/java/org/olat/modules/ceditor/ui/HTMLRawEditorController.java index ca38556f14baf711c562f6a41a110fdbb44cd494..30aa40be3ebc94f14321000827560248c8cbc801 100644 --- a/src/main/java/org/olat/modules/ceditor/ui/HTMLRawEditorController.java +++ b/src/main/java/org/olat/modules/ceditor/ui/HTMLRawEditorController.java @@ -107,7 +107,7 @@ public class HTMLRawEditorController extends FormBasicController implements Page @Override public List<Link> getOptionLinks() { - List<Link> links = new ArrayList<>(2); + List<Link> links = new ArrayList<>(5); links.add(column4Link); links.add(column3Link); links.add(column2Link); diff --git a/src/main/java/org/olat/modules/ceditor/ui/ImageRunController.java b/src/main/java/org/olat/modules/ceditor/ui/ImageRunController.java index dd8414ca4665c1d49783c70d7525738f52b95c44..257560519ef8717672f950506d70f07f1c12f3a6 100644 --- a/src/main/java/org/olat/modules/ceditor/ui/ImageRunController.java +++ b/src/main/java/org/olat/modules/ceditor/ui/ImageRunController.java @@ -26,7 +26,6 @@ import org.olat.core.commons.services.image.Size; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.image.ImageComponent; -import org.olat.core.gui.components.panel.StackedPanel; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; @@ -104,8 +103,7 @@ public class ImageRunController extends BasicController implements PageRunElemen } mainVC.setDomReplacementWrapperRequired(false); - StackedPanel mainPanel = putInitialPanel(mainVC); - mainPanel.setDomReplaceable(false); + putInitialPanel(mainVC); } public void updateImageSettings(ImageSettings settings, DublinCoreMetadata meta) { diff --git a/src/main/java/org/olat/modules/ceditor/ui/PageEditorV2Controller.java b/src/main/java/org/olat/modules/ceditor/ui/PageEditorV2Controller.java index 0f644a53f705b4c8472a2d3637f893fe92feb251..cd0cb07a3a87e7a6c8524544d5c3274ed80c4c95 100644 --- a/src/main/java/org/olat/modules/ceditor/ui/PageEditorV2Controller.java +++ b/src/main/java/org/olat/modules/ceditor/ui/PageEditorV2Controller.java @@ -63,6 +63,7 @@ import org.olat.modules.ceditor.ui.event.MoveDownElementEvent; import org.olat.modules.ceditor.ui.event.MoveUpElementEvent; import org.olat.modules.ceditor.ui.event.OpenAddElementEvent; import org.olat.modules.ceditor.ui.event.PositionEnum; +import org.olat.modules.ceditor.ui.event.SaveElementEvent; /** * @@ -215,6 +216,8 @@ public class PageEditorV2Controller extends BasicController { doDrop(ureq, (DropToEditorEvent)event); } else if(event instanceof DropToPageElementEvent) { doDrop(ureq, (DropToPageElementEvent)event); + } else if(event instanceof SaveElementEvent) { + fireEvent(ureq, Event.CHANGED_EVENT); } } @@ -228,6 +231,8 @@ public class PageEditorV2Controller extends BasicController { } return true; }, editorCmp, false).visitAll(ureq); + + fireEvent(ureq, Event.CHANGED_EVENT); } private void doCloseEditionEvent(UserRequest ureq, String elementId) { diff --git a/src/main/java/org/olat/modules/ceditor/ui/component/ContentEditorFragmentComponent.java b/src/main/java/org/olat/modules/ceditor/ui/component/ContentEditorFragmentComponent.java index de2c1e07473ac8bd45525c76a1daf776f7f4574b..337d99de699f35b79578949d560c336c55b26f26 100644 --- a/src/main/java/org/olat/modules/ceditor/ui/component/ContentEditorFragmentComponent.java +++ b/src/main/java/org/olat/modules/ceditor/ui/component/ContentEditorFragmentComponent.java @@ -46,6 +46,7 @@ import org.olat.modules.ceditor.ui.event.MoveDownElementEvent; import org.olat.modules.ceditor.ui.event.MoveUpElementEvent; import org.olat.modules.ceditor.ui.event.OpenAddElementEvent; import org.olat.modules.ceditor.ui.event.PositionEnum; +import org.olat.modules.ceditor.ui.event.SaveElementEvent; /** * @@ -147,6 +148,7 @@ public class ContentEditorFragmentComponent extends FormBaseComponentImpl implem break; case "save_element": doCloseEditFragment(); + fireEvent(ureq, new SaveElementEvent(this)); break; case "delete_element": fireEvent(ureq, new DeleteElementEvent(this)); @@ -209,6 +211,7 @@ public class ContentEditorFragmentComponent extends FormBaseComponentImpl implem ((PageElementEditorController)editorPart).setEditMode(false); } setDirty(true); + } @Override diff --git a/src/main/java/org/olat/modules/ceditor/ui/event/SaveElementEvent.java b/src/main/java/org/olat/modules/ceditor/ui/event/SaveElementEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..a0bae30834a09a828f5887c52352e56a6324e881 --- /dev/null +++ b/src/main/java/org/olat/modules/ceditor/ui/event/SaveElementEvent.java @@ -0,0 +1,48 @@ +/** + * <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.ceditor.ui.event; + +import org.olat.core.gui.control.Event; +import org.olat.modules.ceditor.ui.component.ContentEditorFragment; + +/** + * + * Initial date: 24 juin 2020<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class SaveElementEvent extends Event { + + private static final long serialVersionUID = 3300706246686745496L; + + public static final String SAVE_ELEMENT = "ce-save-element"; + + private final ContentEditorFragment component; + + public SaveElementEvent(ContentEditorFragment component) { + super(SAVE_ELEMENT); + this.component = component; + } + + public ContentEditorFragment getComponent() { + return component; + } + +} diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties index f3459050968be28ff654e1112edf675673cc2f1d..46f5889befb4af3726e60ff9267fee01e200a328 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties @@ -166,6 +166,7 @@ type.lectures.enabled.enabled=Ein type.lectures.enabled.disabled=Aus type.lectures.enabled.inherited=Vererbt aus Typ ({0}) unoverride.member=\u00DCbergehen anhalten +user.notfound=$org.olat.group.ui.main\:user.notfound warning.atleastone.member=Sie m\u00FCssen mindestens ein Mitglied w\u00E4hlen. warning.atleastone.resource=Sie m\u00FCssen mindestens ein Kurs w\u00E4hlen. warning.curriculum.element.type.deleted=Dieser Typ ist nicht mehr verf\u00FCgbar. diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties index e2f3c8abcd7fbb9b00e14998f4d01ea8f08598b6..8d8b2ba8da8b9671e0363fe782a1c9dd573cbc02 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties @@ -166,6 +166,7 @@ type.lectures.enabled.enabled=On type.lectures.enabled.inherited=Inherited from type ({0}) type.lectures.enabled.on=On unoverride.member=Stop override +user.notfound=$org.olat.group.ui.main\:user.notfound warning.atleastone.member=You need to choose at least one member. warning.atleastone.resource=You need to choose at least one course. warning.curriculum.element.type.deleted=This type is no longer available. diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_fr.properties index 2d1fd10e619a9854b61604a2257f923ffc21eda2..b6a98417bae29b3f411c30d733fc512f1ba8f3ea 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_fr.properties @@ -166,6 +166,7 @@ type.lectures.enabled.enabled=activ\u00E9 type.lectures.enabled.inherited=h\u00E9rit\u00E9 du type (activ\u00E9) type.lectures.enabled.on=Activ\u00E9 unoverride.member=Retour en gestion ext\u00E9rieur +user.notfound=$org.olat.group.ui.main\:user.notfound warning.atleastone.member=Vous devez choisir au moins une personne. warning.atleastone.resource=Vous devez choisir au moins un cours. warning.curriculum.element.type.deleted=Le type n'est plus disponible. diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_it.properties index 27a59be09e006d2a87ff612fe8bed14359c81e13..efa760041eb3fc7c1b7e91b858e37f9c5d7fa4bb 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_it.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_it.properties @@ -1,4 +1,5 @@ #Wed Feb 01 13:37:33 CET 2017 override.member=Scavalcare gestione esterna unoverride.member=Annullare scavalcamento +user.notfound=$org.olat.group.ui.main\:user.notfound zoom=<i class='o_icon o_icon-fw o_icon_enlarge'> </i> diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_pt_BR.properties index 51568d96c62d8a11833c2b98d0e2237d12d12665..a43567dec889db7d0ab530dc554c7037afd258e3 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_pt_BR.properties @@ -166,6 +166,7 @@ type.lectures.enabled.enabled=Lig type.lectures.enabled.inherited=Herdado do tipo ({0}) type.lectures.enabled.on=Lig unoverride.member=Interromper altera\u00E7\u00E3o/sobreposi\u00E7\u00E3o +user.notfound=$org.olat.group.ui.main\:user.notfound warning.atleastone.member=Voc\u00EA precisa escolher pelo menos um membro. warning.atleastone.resource=Voc\u00EA precisa escolher pelo menos um curso. warning.curriculum.element.type.deleted=Este tipo n\u00E3o est\u00E1 mais dispon\u00EDvel. diff --git a/src/main/java/org/olat/modules/docpool/webdav/DocumentPoolWebDAVMergeSource.java b/src/main/java/org/olat/modules/docpool/webdav/DocumentPoolWebDAVMergeSource.java index 815710df72776c6da1fbcc266194cf41598641de..b6a137ed7567b6b6b36094f2469e9040c7d28750 100644 --- a/src/main/java/org/olat/modules/docpool/webdav/DocumentPoolWebDAVMergeSource.java +++ b/src/main/java/org/olat/modules/docpool/webdav/DocumentPoolWebDAVMergeSource.java @@ -129,7 +129,6 @@ class DocumentPoolWebDAVMergeSource extends WebDAVMergeSource { VFSContainer documents = taxonomyService.getDocumentsLibrary(taxonomy); SubscriptionContext subscriptionCtx = notificationsHandler.getTaxonomyDocumentsLibrarySubscriptionContext(); TaxonomyVFSSecurityCallback secCallback = new TaxonomyVFSSecurityCallback(taxonomyNode, subscriptionCtx); - System.out.println(taxonomyNode.isCanWrite()); documents.setLocalSecurityCallback(secCallback); return new NamedContainerImpl(taxonomyNode.getTitle(), documents); } diff --git a/src/main/java/org/olat/modules/forms/ui/RubricEditorController.java b/src/main/java/org/olat/modules/forms/ui/RubricEditorController.java index d333eabcdaeee3a917c9d1d59dbebb62131d15b4..8deaafaa705422bf5b92f1b61ebc2ad47e0470e4 100644 --- a/src/main/java/org/olat/modules/forms/ui/RubricEditorController.java +++ b/src/main/java/org/olat/modules/forms/ui/RubricEditorController.java @@ -238,14 +238,14 @@ public class RubricEditorController extends FormBasicController implements PageE String insufficientLowerBound = rubric.getLowerBoundInsufficient() != null ? String.valueOf(rubric.getLowerBoundInsufficient()) : null; - lowerBoundInsufficientEl = uifactory.addTextElement("rubric.lower.bound.insufficient", 4, + lowerBoundInsufficientEl = uifactory.addTextElement("rubric.lower.bound.insufficient", null, 4, insufficientLowerBound, insufficientCont); lowerBoundInsufficientEl.setDomReplacementWrapperRequired(false); lowerBoundInsufficientEl.setDisplaySize(4); String insufficientUpperBound = rubric.getUpperBoundInsufficient() != null ? String.valueOf(rubric.getUpperBoundInsufficient()) : null; - upperBoundInsufficientEl = uifactory.addTextElement("rubric.upper.bound.insufficient", 4, + upperBoundInsufficientEl = uifactory.addTextElement("rubric.upper.bound.insufficient", null, 4, insufficientUpperBound, insufficientCont); upperBoundInsufficientEl.setDomReplacementWrapperRequired(false); upperBoundInsufficientEl.setDisplaySize(4); @@ -260,12 +260,12 @@ public class RubricEditorController extends FormBasicController implements PageE neutralCont.setHelpTextKey("rubric.rating.help", new String[] { translate("rubric.neutral")} ); String neutralLowerBound = rubric.getLowerBoundNeutral() != null ? String.valueOf(rubric.getLowerBoundNeutral()) : null; - lowerBoundNeutralEl = uifactory.addTextElement("rubric.lower.bound.neutral", 4, neutralLowerBound, neutralCont); + lowerBoundNeutralEl = uifactory.addTextElement("rubric.lower.bound.neutral", null, 4, neutralLowerBound, neutralCont); lowerBoundNeutralEl.setDomReplacementWrapperRequired(false); lowerBoundNeutralEl.setDisplaySize(4); String neutralUpperBound = rubric.getUpperBoundNeutral() != null ? String.valueOf(rubric.getUpperBoundNeutral()) : null; - upperBoundNeutralEl = uifactory.addTextElement("rubric.upper.bound.neutral", 4, neutralUpperBound, neutralCont); + upperBoundNeutralEl = uifactory.addTextElement("rubric.upper.bound.neutral", null, 4, neutralUpperBound, neutralCont); upperBoundNeutralEl.setDomReplacementWrapperRequired(false); upperBoundNeutralEl.setDisplaySize(4); @@ -280,14 +280,14 @@ public class RubricEditorController extends FormBasicController implements PageE String sufficientLowerBound = rubric.getLowerBoundSufficient() != null ? String.valueOf(rubric.getLowerBoundSufficient()) : null; - lowerBoundSufficientEl = uifactory.addTextElement("rubric.lower.bound.sufficient", 4, sufficientLowerBound, + lowerBoundSufficientEl = uifactory.addTextElement("rubric.lower.bound.sufficient", null, 4, sufficientLowerBound, sufficientCont); lowerBoundSufficientEl.setDomReplacementWrapperRequired(false); lowerBoundSufficientEl.setDisplaySize(4); String sufficientUpperBound = rubric.getUpperBoundSufficient() != null ? String.valueOf(rubric.getUpperBoundSufficient()) : null; - upperBoundSufficientEl = uifactory.addTextElement("rubric.upper.bound.sufficient", 4, sufficientUpperBound, + upperBoundSufficientEl = uifactory.addTextElement("rubric.upper.bound.sufficient", null, 4, sufficientUpperBound, sufficientCont); upperBoundSufficientEl.setDomReplacementWrapperRequired(false); upperBoundSufficientEl.setDisplaySize(4); @@ -490,7 +490,7 @@ public class RubricEditorController extends FormBasicController implements PageE // weight String weight = slider.getWeight() != null? slider.getWeight().toString(): ""; - TextElement weightEl = uifactory.addTextElement("weight" + count.incrementAndGet(), 4, weight, flc); + TextElement weightEl = uifactory.addTextElement("weight" + count.incrementAndGet(), null, 4, weight, flc); weightEl.setElementCssClass("o_slider_weight"); weightEl.setExampleKey("slider.weight", null); weightEl.setEnabled(!restrictedEditWeight); diff --git a/src/main/java/org/olat/registration/RegistrationController.java b/src/main/java/org/olat/registration/RegistrationController.java index c90ec44ae5aaf21c5d964b168eb78922b61bc0ea..fa224b77d6fe6dd45ef410e2a1b96392ab44035c 100644 --- a/src/main/java/org/olat/registration/RegistrationController.java +++ b/src/main/java/org/olat/registration/RegistrationController.java @@ -386,7 +386,6 @@ public class RegistrationController extends BasicController implements Activatea if(!htmlBody) { body += SEPARATOR + translate("reg.wherefrom", whereFromAttrs); } - System.out.println(body); if(sendMessage(email, translate("reg.subject"), body)) { showInfo("email.sent"); diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_15_0_3.java b/src/main/java/org/olat/upgrade/OLATUpgrade_15_0_3.java index bfb54e6e64abdbab13ff0be78c98c081d964e716..a7923a0977f66649c2a132ab12ef96cc3a6709ef 100644 --- a/src/main/java/org/olat/upgrade/OLATUpgrade_15_0_3.java +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_15_0_3.java @@ -49,9 +49,14 @@ public class OLATUpgrade_15_0_3 extends OLATUpgrade { private static final Logger log = Tracing.createLoggerFor(OLATUpgrade_15_0_3.class); + private static final int BATCH_SIZE = 50000; + private static final String VERSION = "OLAT_15.0.3"; private static final String ASSESSMENT_LAST_ATTEMPTS = "ASSESSMENT LAST ATTEMPTS"; + private final AtomicInteger migrationLogCounter = new AtomicInteger(0); + private final AtomicInteger migrationEntryCounter = new AtomicInteger(0); + @Autowired private DB dbInstance; @Autowired @@ -97,10 +102,35 @@ public class OLATUpgrade_15_0_3 extends OLATUpgrade { boolean allOk = true; if (!uhd.getBooleanDataValue(ASSESSMENT_LAST_ATTEMPTS)) { try { - List<LoggingObject> loggedLaunches = getLoggedLastAttempts(); - migrateLoggedAttempts(loggedLaunches); - List<AssessmentEntry> entries = getEmptyLastAttempts(); - migrateEmptyLastAttempts(entries); + int counter = 0; + List<LoggingObject> loggedLaunches; + do { + loggedLaunches = getLoggedLastAttempts(counter, BATCH_SIZE); + migrateLoggedAttempts(loggedLaunches); + counter += loggedLaunches.size(); + log.info(Tracing.M_AUDIT, "Log launch processed: {}, total processed ({})", loggedLaunches.size(), counter); + dbInstance.commitAndCloseSession(); + } while(loggedLaunches.size() == BATCH_SIZE); + + log.info(Tracing.M_AUDIT, "Log launch processing successful, total processed: {}", migrationLogCounter); + } catch (Exception e) { + log.error("", e); + allOk = false; + } + + try { + + int counter = 0; + List<AssessmentEntry> entries; + do { + entries = getEmptyLastAttempts(counter, BATCH_SIZE); + migrateEmptyLastAttempts(entries); + counter += entries.size(); + log.info(Tracing.M_AUDIT, "Empty last attempts processed: {}, total processed ({})", entries.size(), counter); + dbInstance.commitAndCloseSession(); + } while(entries.size() == BATCH_SIZE); + + log.info("Assessment entry last attemps processing successful, total processed: {}", migrationEntryCounter); log.info("Assessment last modified migrated."); } catch (Exception e) { log.error("", e); @@ -112,7 +142,7 @@ public class OLATUpgrade_15_0_3 extends OLATUpgrade { return allOk; } - private List<LoggingObject> getLoggedLastAttempts() { + private List<LoggingObject> getLoggedLastAttempts(int firstResult, int maxResults) { QueryBuilder sb = new QueryBuilder(); sb.append("select log"); sb.append(" from loggingobject log"); @@ -121,29 +151,29 @@ public class OLATUpgrade_15_0_3 extends OLATUpgrade { return dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), LoggingObject.class) + .setFirstResult(firstResult) + .setMaxResults(maxResults) .getResultList(); } private void migrateLoggedAttempts(List<LoggingObject> loggedAttempts) { - log.info("Migraton of {} assessment last attemps (log table) started.", loggedAttempts.size()); - Map<Long, Identity> identityCache = new HashMap<>(); Map<Long, RepositoryEntry> entryCache = new HashMap<>(); - AtomicInteger migrationCounter = new AtomicInteger(0); + for (LoggingObject loggingObject : loggedAttempts) { try { migrateLastAttempt(loggingObject, identityCache, entryCache); - migrationCounter.incrementAndGet(); + migrationLogCounter.incrementAndGet(); } catch (Exception e) { log.warn("Assessment last attempt (log table) not migrated. Id={}", loggingObject.getKey()); } - if(migrationCounter.get() % 25 == 0) { + if(migrationLogCounter.get() % 25 == 0) { dbInstance.commitAndCloseSession(); } else { dbInstance.commit(); } - if(migrationCounter.get() % 100 == 0) { - log.info("Assessment: num. of last attempts (log table): {}", migrationCounter); + if(migrationLogCounter.get() % 100 == 0) { + log.info("Assessment: num. of last attempts (log table): {}", migrationLogCounter); } } } @@ -196,20 +226,20 @@ public class OLATUpgrade_15_0_3 extends OLATUpgrade { } } - private List<AssessmentEntry> getEmptyLastAttempts() { + private List<AssessmentEntry> getEmptyLastAttempts(int firstResult, int maxResults) { StringBuilder sb = new StringBuilder(); sb.append("select data from assessmententry data"); sb.append(" where data.attempts > 0 and lastAttempt is null"); - + sb.append(" order by data.key asc"); + return dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), AssessmentEntry.class) + .setFirstResult(firstResult) + .setMaxResults(maxResults) .getResultList(); } private void migrateEmptyLastAttempts(List<AssessmentEntry> entries) { - log.info("Migraton of {} assessment last attemps (empty) started.", entries.size()); - - AtomicInteger migrationCounter = new AtomicInteger(0); for (AssessmentEntry assessmentEntry: entries) { try { if (assessmentEntry.getAttempts() != null && assessmentEntry.getAttempts().intValue() > 0 && assessmentEntry.getLastAttempt() == null) { @@ -219,17 +249,17 @@ public class OLATUpgrade_15_0_3 extends OLATUpgrade { assessmentEntry.setLastAttempt(lastAttemps); assessmentService.updateAssessmentEntry(assessmentEntry); } - migrationCounter.incrementAndGet(); + migrationEntryCounter.incrementAndGet(); } catch (Exception e) { log.warn("Assessment last attempt (empty) not migrated. Id={}", assessmentEntry.getKey()); } - if(migrationCounter.get() % 25 == 0) { + if(migrationEntryCounter.get() % 25 == 0) { dbInstance.commitAndCloseSession(); } else { dbInstance.commit(); } - if(migrationCounter.get() % 100 == 0) { - log.info("Assessment: num. of last attempts (empty): {}", migrationCounter); + if(migrationEntryCounter.get() % 100 == 0) { + log.info("Assessment: num. of last attempts (empty): {}", migrationEntryCounter); } } } diff --git a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml index ad52d24292635fa227d77be22b4bbdf4ed0ec8e7..edd4476ac5521cd046fc0c30f275f76c7ab6d739 100644 --- a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml +++ b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml @@ -224,6 +224,10 @@ <constructor-arg index="0" value="OLAT_14.2.7" /> <property name="alterDbStatements" value="alter_14_2_x_to_14_2_7.sql" /> </bean> + <bean id="database_upgrade_14_2_13" class="org.olat.upgrade.DatabaseUpgrade"> + <constructor-arg index="0" value="OLAT_14.2.13" /> + <property name="alterDbStatements" value="alter_14_2_x_to_14_2_13.sql" /> + </bean> <bean id="database_upgrade_15_pre_0" class="org.olat.upgrade.DatabaseUpgrade"> <constructor-arg index="0" value="OLAT_15.pre.0" /> <property name="alterDbStatements" value="alter_14_2_x_to_15_pre_0.sql" /> diff --git a/src/main/resources/database/mysql/alter_14_2_x_to_14_2_13.sql b/src/main/resources/database/mysql/alter_14_2_x_to_14_2_13.sql new file mode 100644 index 0000000000000000000000000000000000000000..35ad20bf9472a62d158c4777d44bfc6145111bb6 --- /dev/null +++ b/src/main/resources/database/mysql/alter_14_2_x_to_14_2_13.sql @@ -0,0 +1,4 @@ +alter table o_as_mode_course modify a_elements text(32000); +alter table o_as_mode_course modify a_ips text(32000); +alter table o_as_mode_course modify a_safeexambrowserkey text(32000); + diff --git a/src/main/resources/database/oracle/alter_14_2_x_to_14_2_13.sql b/src/main/resources/database/oracle/alter_14_2_x_to_14_2_13.sql new file mode 100644 index 0000000000000000000000000000000000000000..c7d4908afd6e9737c97a08f650f9a492a4abe103 --- /dev/null +++ b/src/main/resources/database/oracle/alter_14_2_x_to_14_2_13.sql @@ -0,0 +1,4 @@ +alter table o_as_mode_course modify a_elements varchar(32000); +alter table o_as_mode_course modify a_ips varchar(32000); +alter table o_as_mode_course modify a_safeexambrowserkey varchar(32000); + diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index 337d43a491520dbb4a8db00162bce73b27fec42e..1079566432d571080112c0470ecca8522f102df0 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -1382,12 +1382,12 @@ create table o_as_mode_course ( a_end_with_followuptime date not null, a_targetaudience varchar2(16 char), a_restrictaccesselements number default 0 not null, - a_elements varchar2(2048 char), + a_elements varchar2(32000 char), a_start_element varchar2(64 char), a_restrictaccessips number default 0 not null, - a_ips varchar2(2048 char), + a_ips varchar2(32000 char), a_safeexambrowser number default 0 not null, - a_safeexambrowserkey varchar2(2048 char), + a_safeexambrowserkey varchar2(32000 char), a_safeexambrowserhint clob, a_applysettingscoach number default 0 not null, fk_entry number(20) not null, diff --git a/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_13.sql b/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_13.sql new file mode 100644 index 0000000000000000000000000000000000000000..ec9c158de681214c035670d1e96afe09c73f1027 --- /dev/null +++ b/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_13.sql @@ -0,0 +1,4 @@ +alter table o_as_mode_course alter column a_elements type varchar(32000); +alter table o_as_mode_course alter column a_ips type varchar(32000); +alter table o_as_mode_course alter column a_safeexambrowserkey type varchar(32000); + diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index 8d32312bf29687312912335a9e6b027682523ecc..83f9c985cfc37312e1a5cce137060c826dfd621a 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -1342,12 +1342,12 @@ create table o_as_mode_course ( a_end_with_followuptime timestamp not null, a_targetaudience varchar(16), a_restrictaccesselements bool not null default false, - a_elements varchar(2048), + a_elements varchar(32000), a_start_element varchar(64), a_restrictaccessips bool not null default false, - a_ips varchar(2048), + a_ips varchar(32000), a_safeexambrowser bool not null default false, - a_safeexambrowserkey varchar(2048), + a_safeexambrowserkey varchar(32000), a_safeexambrowserhint text, a_applysettingscoach bool not null default false, fk_entry int8 not null, diff --git a/src/main/resources/infinispan-config.xml b/src/main/resources/infinispan-config.xml index 327897d29940caa5b3877c1d2f0758c24a67a6bd..9bffb517b65388aa3ef58123dbfa86a2df2cbb45 100644 --- a/src/main/resources/infinispan-config.xml +++ b/src/main/resources/infinispan-config.xml @@ -80,6 +80,24 @@ <expiration max-idle="180000" interval="15000" /> </local-cache> + <local-cache name="QTIWorks@assessmentTests" simple-cache="true" statistics="true" statistics-available="true"> + <locking isolation="READ_COMMITTED" concurrency-level="1000" acquire-timeout="15000" striping="false" /> + <transaction mode="NONE" auto-commit="true" /> + <memory> + <object size="200" strategy="REMOVE" /> + </memory> + <expiration max-idle="900000" interval="15000" /> + </local-cache> + + <local-cache name="QTIWorks@xsltStylesheets" simple-cache="true" statistics="true" statistics-available="true"> + <locking isolation="READ_COMMITTED" concurrency-level="1000" acquire-timeout="15000" striping="false" /> + <transaction mode="NONE" auto-commit="true" /> + <memory> + <object size="200" strategy="REMOVE" /> + </memory> + <expiration max-idle="1800000" interval="15000" /> + </local-cache> + <local-cache name="WebDAVManager@webdav" simple-cache="true" statistics="true" statistics-available="true"> <locking isolation="READ_COMMITTED" concurrency-level="1000" acquire-timeout="15000" striping="false" /> <transaction mode="NONE" auto-commit="true" /> diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties index 54d55dee5009c7eddff754241b3910808cc65d4a..32fa39213a6d7d87b3ec1c76bc5735188fcb5d21 100644 --- a/src/main/resources/serviceconfig/olat.properties +++ b/src/main/resources/serviceconfig/olat.properties @@ -1268,8 +1268,8 @@ ldap.learningResourceManagerRoleValue= # Build properties ##### application.name=OpenOlat -build.version=15.0.4 -build.identifier=openolat1504-dev +build.version=15.0.5 +build.identifier=openolat1505-dev build.repo.revision=local-devel ##### diff --git a/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java b/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java index d229a6416a04bbf223700dfcb385cc265c0fb43f..f696bb962562d5441ed369198096f889adf13b9b 100644 --- a/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java +++ b/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java @@ -64,8 +64,13 @@ public class CoursePageFragment { } public static CoursePageFragment getCourse(WebDriver browser, URL deploymentUrl, CourseVO course) { - browser.navigate().to(deploymentUrl.toExternalForm() + "url/RepositoryEntry/" + course.getRepoEntryKey()); - OOGraphene.waitElement(courseRun, browser); + browser.get(deploymentUrl.toExternalForm() + "url/RepositoryEntry/" + course.getRepoEntryKey()); + try { + OOGraphene.waitElementSlowly(courseRun, 10, browser); + } catch (Exception e) { + OOGraphene.takeScreenshot("GetcourseByGet", browser); + throw e; + } return new CoursePageFragment(browser); }