%PDF- %PDF-
Direktori : /home/waritko/jetty-distribution-9.4.21.v20190926/webapps/ROOT/templates/ |
Current File : //home/waritko/jetty-distribution-9.4.21.v20190926/webapps/ROOT/templates/extension.vm |
## Make sure the browser won't keep the same version of the resource in cache from one version of XWiki to another #set($environmentVersion = $services.extension.core.repository.environmentExtension.id.version) #set ($discard = $xwiki.ssfx.use('uicomponents/extension/extension.css', {'forceSkinAction': true, 'version': $environmentVersion})) #set ($discard = $xwiki.jsfx.use('uicomponents/extension/extension.js', {'forceSkinAction': true, 'version': $environmentVersion})) #set ($discard = $xwiki.ssfx.use('uicomponents/viewers/diff.css', {'forceSkinAction': true, 'version': $environmentVersion})) #set ($discard = $xwiki.jsfx.use('uicomponents/viewers/diff.js', {'forceSkinAction': true, 'version': $environmentVersion})) #set ($discard = $xwiki.ssfx.use('uicomponents/widgets/buttonGroup.css', {'forceSkinAction': true, 'version': $environmentVersion})) #set ($discard = $xwiki.jsfx.use('uicomponents/widgets/buttonGroup.js', {'forceSkinAction': true, 'version': $environmentVersion})) #set($discard = $services.template.execute('job_macros.vm')) #set($discard = $services.template.execute('rating_macros.vm')) ## Various configuration of extension.vm behavior ## * skipCheckRight: skip right validation when executing a action (install plan, install, etc.) ## * skipCurrentUser: don't take into account context use (XAR extension documents will keep their author for example) ## * installJAROnRoot: force installing JAR extensions on root namespaces #if (!$extensionConfig) #set ($extensionConfig = {}) #end #set ($extensionManager = $services.extension) ## From the main wiki we can manage other namespaces. #if ($xcontext.isMainWiki() && "$!request.extensionNamespace" != '') #set ($extensionNamespace = $request.extensionNamespace) #else #set ($extensionNamespace = "wiki:$xcontext.database") #end #set ($isAjaxRequest = $request.getHeader('X-Requested-With') == 'XMLHttpRequest') #macro (displayExtensionSearchBar) <div class="extension-search-bar"> ## Simple search form. <form action="$xwiki.relativeRequestURL" id="extension-search-simple" class="form-inline"> <div> #if ($request.section) <input type="hidden" name="section" value="$escapetool.xml($request.section)" /> #end <label class="hidden" for="extensionSearchInput">$services.localization.render('extensions.search.tip')</label> <input type="text" id="extensionSearchInput" name="search" #if ("$!request.search" != '') value="$escapetool.xml($request.search)"#{end} placeholder="$services.localization.render('extensions.search.tip')"/> <label class="hidden" for="extensionSearchRepositoryList">$services.localization.render('extensions.search.repository.label')</label> #set ($selectedRepositoryId = 'recommended') #if ($request.repo) #set ($selectedRepositoryId = $request.repo) #end <select id="extensionSearchRepositoryList" name="repo"> <optgroup label="$services.localization.render('extension.search.repositoryGroup.remote.label')"> ## Remote extensions repository <option value=""#if ($selectedRepositoryId == '') selected="selected"#end> $services.localization.render('extensions.search.repository.remote.label') </option> ## Recommended extensions repository (default) <option value="recommended"#if ($selectedRepositoryId == 'recommended') selected="selected"#end> $services.localization.render("extensions.search.repository.recommended.label") </option> </optgroup> <optgroup label="$services.localization.render('extension.search.repositoryGroup.local.label')"> ## Local repositories #foreach ($repositoryId in ['installed', 'local', 'core']) <option value="$repositoryId"#if ($selectedRepositoryId == $repositoryId) selected="selected"#end> $services.localization.render("extensions.search.repository.${repositoryId}.label")</option> #end </optgroup> </select> ## We don't use #em_submitButton because we want to use <button> instead of <input type="submit">, in order to ## be able to use HTML content inside the text of the button (the search icon and the hidden span for screen readers). <span class="buttonwrapper"> <button class="primary" type="submit">$services.icon.renderHTML('search') <span class="hidden">$escapetool.xml($services.localization.render('extensions.advancedSearch.actions.submit'))</span></button> </span> </div> </form> ## Advanced search form. <form action="$xwiki.relativeRequestURL" class="xform"> <fieldset id="extension-search-advanced"> <legend><a href="#extension-search-advanced-body">$services.localization.render('extensions.advancedSearch.title')</a></legend> <div id="extension-search-advanced-body"></div> <div class="plainmessage extension-search-advanced-popup hidden"> #if ($request.section) <input type="hidden" name="section" value="$escapetool.xml($request.section)" /> #end <dl> <dt><label for="advancedExtensionSearch-id">$services.localization.render('extensions.advancedSearch.id.label')</label></dt> <dd><input type="text" name="extensionId" id="advancedExtensionSearch-id" value="" /></dd> <dt><label for="advancedExtensionSearch-version">$services.localization.render('extensions.advancedSearch.version.label')</label></dt> <dd><input type="text" name="extensionVersion" id="advancedExtensionSearch-version" value="" /></dd> </dl> <p> #em_submitButton('extensions.advancedSearch.actions.submit') #em_linkButton('#extension-search-simple' 'extensions.advancedSearch.actions.cancel' 'actionCancel') </p> </div> </fieldset> </form> <div class="clearfloats"></div> </div> #end #macro (displayExtensionName $extension) #set ($name = "$!{extension.name}") #if ($name == '') #set ($name = "$!{extension.id.id}") #if ($name.indexOf(':') >= 0) #set ($name = $name.substring($mathtool.add($name.indexOf(':'), 1))) #end #end ${name}## #end #macro (displayExtensionActionButtons $extension $readOnly) <div class="extension-actions"> #displayExtensionActionButtons_detailsToggle($extension) #if (!$readOnly) ## Group the buttons that trigger an extension job. <span class="dynamic-button-group"> #displayExtensionActionButtons_jobTriggers($extension) </span> #end </div> #end #macro (displayExtensionActionButtons_detailsToggle $extension) #computeXBack() #if ($showExtensionDetails) #if ($isAjaxRequest) ## AJAX request to show extension details. #extensionActionButton('showDetails' true 'visibilityAction') #extensionActionButton('hideDetails' true 'visibilityAction') #else ## The given extension is displayed alone. #em_linkButton($xback 'extensions.actions.back' 'extension-link') #end #else ## The given extension is displayed in a list of extensions. #extensionActionButton('showDetails' true) #end ## Make sure the URL to get back is preserved when we submit an extension action. <input type="hidden" name="xback" value="$escapetool.xml($xback)" /> #end #macro (displayExtensionActionButtons_jobTriggers $extension) #if(!$extensionStatus) #determineExtensionStatus($extension $extensionStatus $extensionStatusMessage) #end ## Determine if there is an extension job waiting to be resumed or a previously created job plan that can be executed. #set ($showContinueButton = $jobState == 'WAITING') #if (!$showContinueButton) #isExtensionPlan($jobStatus $showContinueButton) #end #if ($showContinueButton) ## One of the following statements is true: ## * the current extension job is waiting for user input and the user needs a button to resume the job, ## * an extension job plan was previously computed and the user needs a button to execute the plan. #extensionActionButton('continue') <input name="form_token" value="$!services.csrf.getToken()" type="hidden" /> #if ($jobState == 'WAITING') ## Only the Continue button should be available when a job is waiting. #break #end #end ## Note that the Continue button doesn't exclude the following buttons, unless a job is waiting. The user should be ## able for instance to recompute the install plan. #if ($extensionStatus.startsWith('installed')) ## The given extension object could be an instance of LocalExtension so make sure we use an InstalledExtension instance. #getInstalledExtension($extension $extensionNamespace $installedExtension) ## If the installed extension might be invalid and need repairing #extensionRepairButtons($installedExtension) ## This extension can be uninstalled #extensionUninstallButtons($installedExtension) ## XAR specific buttons #extensionActionXARButtons($installedExtension) ## If the extension is not installed on farm propose it #if (!$installedExtension.isInstalled($NULL)) #extensionActionGlobalButton('install' false) #end #elseif ($extensionStatus == 'remote') ## Installable extension. #if ($xcontext.action == 'distribution' && $showRepairXARButton) ## NOTE: This code is normally reached only when JavaScript is disabled since otherwise the button is added from JavaScript. ## TODO: Find a better way to 'force' the repair XAR extension button. #set ($showRepairXARButton = $NULL) #extensionActionButton('repairXAR') ## The repair job is executed without confirmation (i.e. without a plan). <input name="form_token" value="$!services.csrf.getToken()" type="hidden" /> #else #extensionInstallButtons($extension) #end #elseif ($extensionStatus.startsWith('remote-installed')) ## An extension that can be either upgraded or downgraded. ## Compare this version with the version that is currently installed to determine which button to display. #getInstalledExtension($extension $extensionNamespace $installedExtension) #if ($extension.compareTo($installedExtension) > 0) #extensionUpgradeButtons($installedExtension 'upgrade') #else #extensionUpgradeButtons($installedExtension 'downgrade' true) #end ## If the extension is not installed on farm propose it #if (!$installedExtension.isInstalled($NULL)) #extensionActionGlobalButton('install' false) #end #end #end #macro(extensionInstallButtons $extension) #set($isGlobalActionSecondary = false) #if ($services.extension.isAllowed($extension, $extensionNamespace)) #extensionActionButton('install') #set($isGlobalActionSecondary = true) #end #if ($services.extension.isAllowed($extension, $NULL)) #extensionActionGlobalButton('install' $isGlobalActionSecondary) #end #end #macro(extensionUpgradeButtons $installedExtension $displayHint $secondary) #if ($installedExtension.isInstalled($NULL)) ## It's installed on root, lets upgrade on root #extensionActionGlobalButtonWithDisplayHint('install' $displayHint $secondary) ## Also propose to install it on farm #extensionActionButton('install' true) #elseif ($installedExtension.isInstalled($extensionNamespace)) ## It's installed on provided namespace, lets upgrade on provided namespace #extensionActionButtonWithDisplayHint('install' $displayHint $secondary) #end #end #macro(extensionRepairButtons $installedExtension) #if ($installedExtension.isInstalled($NULL)) #if (!$installedExtension.isValid($NULL)) ## It's invalid on root namespace #extensionActionGlobalButtonWithDisplayHint('install' 'repair') #end #elseif ($installedExtension.isInstalled($extensionNamespace) && !$installedExtension.isValid($extensionNamespace)) ## It's invalid on provided namespace #extensionActionButtonWithDisplayHint('install' 'repair') #end #end #macro(extensionUninstallButtons $installedExtension) #if (!$installedExtension.isInstalled($NULL) && $installedExtension.isInstalled($extensionNamespace)) ## It's installed on provided namespace #extensionActionButton('uninstall' true) #end ## It might be installed somewhere else, propose to remove it from the whole farm #extensionActionGlobalButton('uninstall' true) #end #macro(extensionActionXARButtons $installedExtension) #if ($installedExtension.type == 'xar' && $installedExtension.isInstalled($extensionNamespace)) ## Add the button that can be used to compute the differences between the documents from the XAR and the documents ## from the database. #extensionActionButton('diffXAR' true) #end #end #macro (displayExtensionRating $extension) #set ($rating = $extension.getRating()) #if ($rating != $NULL) #set($id = $xwiki.getUniquePageName("string").replaceAll("[0-9]*", "").toLowerCase()) <div class="extension-rating"> #ratingstars($id "" "" $rating.averageVote $rating.totalVotes true) </div> #end #end #macro (displayExtensionAuthors $extension) #set ($authors = []) #foreach ($author in $extension.authors) #if ($author.name == 'devs') #set ($discard = $authors.add("<a class=""extension-author"" href=""http://www.xwiki.org/"">$services.localization.render('extensions.info.authors.xwikiorg')</a>")) #elseif ("$!author.url" != '' && "$!author.name" != '') #set ($discard = $authors.add("<a class=""extension-author"" href=""$author.url"">$escapetool.xml($author.name)</a>")) #else #set ($discard = $authors.add("<span class=""extension-author"">$escapetool.xml($author.name)</span>")) #end #end #if (!$authors.isEmpty()) <p class="extension-authors">$services.localization.render('extensions.info.authors') $stringtool.join($authors, ', ')</p> #end #end #macro (displayProgressBar $extension) #if (!$jobStatus || !$jobStatus.request.extensions.contains($extension.id)) #getExtensionJobStatus($extension.id.id $extension.id.version.value $jobStatus) #set ($jobState = $jobStatus.state) #end #if ($jobStatus && $jobState != 'FINISHED') #displayJobProgressBar($jobStatus) #end #end #macro (displayExtensionDetails_menuLink $detail $selected) <a href="#extension-body-${detail}-$extensionIdHashCode"#if ($selected) class="current"#end> $services.localization.render("extensions.info.category.${detail}") </a> #end #macro (displayExtensionDetails_menu $extension) #if (!$jobStatus || !$jobStatus.request.extensions.contains($extension.id)) #getExtensionJobStatus($extension.id.id $extension.id.version.value $jobStatus) #set ($jobState = $jobStatus.state) #end <ul class="innerMenu"> <li>#displayExtensionDetails_menuLink('description')</li>## ## #if ($extension.dependencies.size() > 0 || $backwardDependencies.size() > 0) <li>#displayExtensionDetails_menuLink('dependencies')</li>## #end ## #if ($jobStatus) #if ($jobState == 'FINISHED' && $jobStatus.documentDiffs) <li>#displayExtensionDetails_menuLink('changes')</li>## #end #set ($selected = $jobState != 'FINISHED' || $request.extensionSection == 'progress') <li>#displayExtensionDetails_menuLink('progress' $selected)</li>## #end </ul> #end #macro (displayExtensionDetails_description $extension) <div id="extension-body-description-$extensionIdHashCode"></div> <dl class="extension-body-description extension-body-section"> <dt>$services.localization.render('extensions.info.id')</dt> <dd>$extension.id.id</dd> #if ($extension.extensionFeatures.size() > 0) <dt>$services.localization.render('extensions.info.features', [$extension.extensionFeatures.size()])</dt> <dd> #if ($extension.extensionFeatures.size() == 1) $escapetool.xml($extension.extensionFeatures.iterator().next().id) #else <ul> #foreach ($feature in $extension.extensionFeatures) <li>$escapetool.xml($feature.id)</li> #end </ul> #end </dd> #end <dt>$services.localization.render('extensions.info.type')</dt> <dd>$extension.type</dd> <dt>$services.localization.render('extensions.info.license', [$extension.licenses.size()])</dt> #if ($extension.licenses.size() > 0) <dd> #if ($extension.licenses.size() == 1) $extension.licenses.iterator().next().name #else <ul> #foreach ($license in $extension.licenses) <li>$license.name</li> #end </ul> #end </dd> #end #if ("$!{extension.webSite}" != '') <dt>$services.localization.render('extensions.info.website')</dt> <dd><a href="$extension.webSite">$escapetool.xml($extension.webSite.replaceAll('^[^/]++//([^/\?]++)[/\?]?.*+$', '$1'))</a></dd> #end #if ($extension.repository.descriptor.URI && $extension.repository.descriptor.URI.scheme != 'file') <dt>$services.localization.render('extensions.info.repository')</dt> <dd><a href="$extension.repository.descriptor.URI">$escapetool.xml($extension.repository.descriptor.id)</a></dd> #end #if ($extension.scm) #if ($extension.scm.url) <dt>$services.localization.render('extensions.info.scm')</dt> <dd><a href="$extension.scm.url">$escapetool.xml($extension.scm.url.replaceAll('^[^/]++//([^/\?]++)[/\?]?.*+$', '$1'))</a></dd> #elseif ($extension.scm.connection) <dt>$services.localization.render('extensions.info.scm')</dt> <dd><a href="$extension.scm.connection.path">$escapetool.xml($extension.scm.connection.system)</a></dd> #end #end #if ($extension.issueManagement.getURL()) <dt>$services.localization.render('extensions.info.issueManagement')</dt> <dd><a href="$extension.issueManagement.getURL()">#if($extension.issueManagement.system)$escapetool.xml($extension.issueManagement.system)#else$escapetool.xml($extension.issueManagement.getURL())#end</a></dd> #end #if ($extension.isInstalled()) #displayExtensionDetails_description_wikis($extension) #end #if ($extensionStatus != 'loading') #displayExtensionDetails_description_versions($extension) #end ## ## TODO: need a decision on what exactly is the description and how it should be safely displayed (wiki syntax, ## server side generated HTML, etc.) ## <dt>Description</dt> ## <dd>$!extension.description</dd> </dl> #end #macro (displayExtensionDetails_description_wikis $extension) #if (!$extension.namespaces || $extension.namespaces.isEmpty()) ## The given extension was installed globally. #getInstallInfo($extension $NULL $install) #if ($install.date) <dt>$services.localization.render('extensions.info.installedGloballyBy', [$xwiki.getUserName($install.userReference), $xwiki.formatDate($install.date)])</dt> #else <dt>$services.localization.render('extensions.info.namespaces.global')</dt> #end #elseif ($xcontext.isMainWiki()) ## Display the list of namespaces where the given extension is installed only if we are on the main wiki. <dt>$services.localization.render('extensions.info.namespaces.list')</dt> <dd><ul> #foreach ($namespace in $extension.namespaces) #getInstallInfo($extension $namespace $install) #if ($install.date) <li>$services.localization.render('extensions.info.installedOnNamespaceBy', [ "#displayExtensionNamespace($namespace)", $xwiki.getUserName($install.userReference), $xwiki.formatDate($install.date) ])</li> #else <li>#displayExtensionNamespace($namespace)</li> #end #end </ul></dd> #else #getInstallInfo($extension $extensionNamespace $install) #if ($install.date) <dt>$services.localization.render('extensions.info.installedBy', [$xwiki.getUserName($install.userReference), $xwiki.formatDate($install.date)])</dt> #end #end #end #macro (getInstallInfo $installedExtension $namespace $return) #set ($install = {'date': $installedExtension.getInstallDate($namespace)}) #if ($install.date) #set ($install.userReference = $installedExtension.getUserReference($namespace)) #else #set ($installJobStatus = $extensionManager.getExtensionJobStatus($installedExtension.id.id, $namespace)) #if ($installJobStatus && $installJobStatus.jobType == 'install') #set ($install.date = $installJobStatus.startDate) #set ($install.userReference = $installJobStatus.request.getProperty('user.reference')) #end #end #set ($return = $NULL) #setVariable("$return" $install) #end #macro (displayExtensionNamespace $namespace) #if ("$!namespace" == '' && $namespace != '') $services.localization.render('extensions.info.globalNamespace')## #elseif ($namespace.startsWith('wiki:')) #wikiHomePageLink($namespace)## #else $namespace## #end #end #macro (displayExtensionDetails_description_versions $extension) <dt>$services.localization.render('extensions.info.stableVersions.label')</dt> <dd> #if (!$request.listVersions) <a href="#getExtensionURL($extension.id.id $extension.id.version.value {'listVersions': true})" class="extension-versions-link"> $services.localization.render('extensions.info.stableVersions.linkLabel') </a> #else #set ($stableVersions = []) #foreach ($version in $extensionManager.resolveVersions($extension.id.id, 0, -1)) #if ($version.type == 'STABLE') #set ($discard = $stableVersions.add($version.value)) #end #end #if ($stableVersions.size() > 0) <ul> ## Latest version first. #foreach ($i in [$mathtool.sub($stableVersions.size(), 1)..0]) #set ($version = $stableVersions.get($i)) <li><a href="#getExtensionURL($extension.id.id $version)" class="extension-link">$version</a></li> #end </ul> #else $services.localization.render('extensions.info.stableVersions.noResults') #end #end </dd> #end #** * NOTE: We explicitly overwrite the $extensionNamespace global variable because we want the dependency status to be * determined for the given namespace. See #determineExtensionStatus() macro. *# #macro (displayDependency $dependencyOrExtension $extensionNamespace $resolveRemotely) #if ($dependencyOrExtension.versionConstraint) ## Dependency object. #set ($dependencyId = $dependencyOrExtension.id) #set ($dependencyVersion = $dependencyOrExtension.versionConstraint) #if ($resolveRemotely) #set ($dependencyExtension = $extensionManager.resolve($dependencyOrExtension, $extensionNamespace)) #else ## Search for the dependency only in the core and local repositories. ## TODO: Check also the remote extensions that have been partially cached locally (e.g. only their pom has been ## downloaded). We need a resolve method that doesn't perform any remote calls. #set ($dependencyExtension = $extensionManager.getRepository('core').resolve($dependencyOrExtension)) #if (!$dependencyExtension) #set ($dependencyExtension = $extensionManager.getRepository('local').resolve($dependencyOrExtension)) #end #end #else ## Extension object. #set ($dependencyId = $dependencyOrExtension.id.id) #set ($dependencyVersion = $dependencyOrExtension.id.version.value) #set ($dependencyExtension = $dependencyOrExtension) #end #set ($dependencyStatus = 'unknown') #set ($dependencyStatusMessage = $NULL) #set ($dependencyName = $dependencyId) #if ($dependencyExtension) ## The extension status is determined for the $extensionNamespace . The name of this parameter is very important ## because it has to overwrite the global variable with the same name. #determineExtensionStatus($dependencyExtension $dependencyStatus $dependencyStatusMessage $dependencyOrExtension.versionConstraint) #set ($dependencyURL = "#getExtensionURL($dependencyId $dependencyVersion)") #set ($dependencyName = "<a href=""$dependencyURL"" class=""extension-link"">#displayExtensionName($dependencyExtension)</a>") #end <div class="dependency-item extension-item-$dependencyStatus"> <span class="extension-name">${dependencyName}</span><span class="extension-version">$!dependencyVersion</span> #if ($extensionNamespace.startsWith('wiki:')) <span class="extension-namespace">$services.localization.render('extensions.info.dependency.wiki', ["#wikiHomePageLink($extensionNamespace)"])</span> #end #if ("$!dependencyStatusMessage" != '') <span class="extension-status">$dependencyStatusMessage</span> #end </div> #end #macro (displayExtensionDetails_dependencies_upstream $extension) #if ($extension.dependencies.size() > 0) <dt>$services.localization.render('extensions.info.dependencies.directDependencies', [$extension.dependencies.size()])</dt> <dd> <ul class="dependencies"> #foreach ($dependency in $extension.dependencies) <li>#displayDependency($dependency $extensionNamespace)</li> #end </ul> </dd> #end #end #macro (displayExtensionDetails_dependencies_downstream $backwardDependencies) #if ($backwardDependencies.size() > 0) <dt>$services.localization.render('extensions.info.dependencies.backwardDependencies', [$backwardDependencies.size()])</dt> <dd> <ul class="dependencies"> #foreach ($namespace in $backwardDependencies.entrySet()) #foreach ($dependency in $namespace.value) <li>#displayDependency($dependency $namespace.key)</li> #end #end </ul> </dd> #end #end #macro (displayExtensionDetails_dependencies $extension $backwardDependencies) #if ($extension.dependencies.size() > 0 || $backwardDependencies.size() > 0) <div id="extension-body-dependencies-$extensionIdHashCode"></div> #computeXBack() <dl class="extension-body-dependencies extension-body-section"> #displayExtensionDetails_dependencies_upstream($extension) #displayExtensionDetails_dependencies_downstream($backwardDependencies) </dl> #end #end #macro (displayExtensionDetails_changes $extension) #if (!$jobStatus || !$jobStatus.request.extensions.contains($extension.id)) #getExtensionJobStatus($extension.id.id $extension.id.version.value $jobStatus) #set ($jobState = $jobStatus.state) #end #set ($documentDiffs = $jobStatus.documentDiffs) #if ($jobState == 'FINISHED' && $documentDiffs) ## Need csrf token for reverts <input name="form_token" value="$!services.csrf.getToken()" type="hidden" /> <div id="extension-body-changes-$extensionIdHashCode"></div> <div class="extension-body-changes extension-body-section"> #template('diff_macros.vm') #displayDocumentUnifiedDiffsWithSummary($documentDiffs 3) </div> #end #end #macro (displayExtensionDetails_progress $extension) #if (!$jobStatus || !$jobStatus.request.extensions.contains($extension.id)) #getExtensionJobStatus($extension.id.id $extension.id.version.value $jobStatus) #set ($jobState = $jobStatus.state) #end #if ($jobStatus) <div id="extension-body-progress-$extensionIdHashCode"></div> <div class="extension-body-progress extension-body-section"> #displayExtensionJobStatus($jobStatus) #if ($jobState == 'WAITING') <div class="extension-question xform"> #displayExtensionDetails_progressQuestion($extension $jobStatus) </div> #end </div> #end #end #macro (displayExtensionJobStatus $jobStatus) #isExtensionPlan($jobStatus $isExtensionPlan) #if ($isExtensionPlan) #displayExtensionPlan($jobStatus) #else ## Display any incompatibility errors #set ($jobStatusCollapsed = false) #if ($jobStatus.state == 'FINISHED') #if ($jobStatus.error && $exceptiontool.getRootCauseMessage($jobStatus.error).contains('not compatible')) #set ($jobStatusCollapsed = true) #set ($errorMessage = $services.localization.render('platform.extension.info.error.versionNotCompatible')) #set ($errorMessage = "${errorMessage}<br/>") #set ($errorMessage = "${errorMessage}${services.localization.render('platform.extension.info.error.versionNotCompatibleHint')}") <p>#error($errorMessage)</p> #end #end #displayJobStatusLog($jobStatus, $jobStatusCollapsed) #end #end #macro (isExtensionPlan $jobStatus $return) #set ($isExtensionPlan = $jobStatus.state == 'FINISHED' && $jobStatus.actions && !$jobStatus.error) #set ($return = $NULL) #setVariable ("$return" $isExtensionPlan) #end #macro (displayExtensionPlan $plan) ## Group the extensions by the actions that will be performed on them. #set($extensionsByAction = {'INSTALL': [], 'UPGRADE': [], 'DOWNGRADE': [], 'UNINSTALL': [], 'REPAIR': []}) #set ($noAction = true) #foreach($planAction in $plan.actions) #set ($targetExtensions = $extensionsByAction.get($planAction.action.name())) #if ($targetExtensions) #set ($discard = $targetExtensions.add($planAction)) #set ($noAction = false) #end #end ## #if ($noAction) #set ($emptyPlanMessageKeys = { 'installplan': 'extensions.install.error.alreadyInstalled', 'uninstallplan': 'extensions.uninstall.error.notInstalled' }) <div class="infomessage">$services.localization.render($emptyPlanMessageKeys.get($plan.jobType))</div> #else <dl> #foreach($entry in $extensionsByAction.entrySet()) #if (!$entry.value.isEmpty()) <dt>$services.localization.render("extensions.install.list.${entry.key.toLowerCase()}")</dt> <dd> <ul class="dependencies"> #foreach ($planAction in $entry.value) <li>#displayDependency($planAction.extension $planAction.namespace)</li> #end </ul> </dd> #end #end </dl> #end #end #macro (displayExtensionDetails_progressQuestion $extension $jobStatus) #set ($question = $jobStatus.question) #set ($questionType = $question.getClass().getName()) #if ($questionType.endsWith('.ConflictQuestion')) #displayExtensionDetails_mergeConflictQuestion($question) #elseif ($questionType.endsWith('.CleanPagesQuestion')) #displayExtensionDetails_cleanPagesQuestion($question) #elseif ($questionType.endsWith('.DefaultConflictActionQuestion')) #displayExtensionDetails_defaultConflictActionQuestion($question) #end #end #macro (displayExtensionDetails_mergeConflictQuestion $question) <dl> <dt> <label>$services.localization.render('extensions.upgrade.mergeConflict.label')</label> <span class="xHint">$services.localization.render('extensions.upgrade.mergeConflict.hint', ["<a href=""$xwiki.getURL($question.currentDocument.documentReference)"">$question.currentDocument</a>"])</span> </dt> <dd> <select name="versionToKeep"> #set ($versions = { 'NEXT': $question.nextDocument, 'MERGED': $question.mergedDocument, 'CURRENT': $question.currentDocument }) #foreach($entry in $versions.entrySet()) ## Make sure that each version has a document associated. We don't have for instance a merged document when ## there is no previous installed version of a XAR extension but the imported documents already exist in the wiki. #if ($entry.value) <option value="$entry.key"#if ($question.globalAction == $entry.key) selected="selected"#end> $services.localization.render("extensions.upgrade.mergeConflict.versionToKeep.${entry.key.toLowerCase()}") </option> #end #end </select> </dd> <dt> <label> <input type="checkbox" name="autoResolve" value="true" /> $services.localization.render('extensions.upgrade.mergeConflict.autoResolve') </label> <span class="xHint">$services.localization.render('extensions.upgrade.mergeConflict.autoResolve.hint')</span> </dt> </dl> #displayExtensionDetails_mergeConflictChanges($question) #end #macro (displayExtensionDetails_mergeConflictChanges $question) <h3 class="extension-diff-title">$services.localization.render('extensions.upgrade.mergeConflict.changes.title', ["<a href=""$xwiki.getURL($question.currentDocument.documentReference)"">$question.currentDocument</a>"])</h3> <div class="extension-diff-options"> #set ($versions = { 'PREVIOUS': $question.previousDocument, 'CURRENT': $question.currentDocument, 'NEXT': $question.nextDocument, 'MERGED': $question.mergedDocument }) <span class="label">$services.localization.render('extensions.upgrade.mergeConflict.changes.original')</span><select name="original"> #if ("$!request.original" != '') #set ($originalVersion = $request.original) #else #set ($originalVersion = 'CURRENT') #end #set ($originalDocument = $versions.get($originalVersion)) #foreach($entry in $versions.entrySet()) #if ($entry.value) <option value="$entry.key"#if ($entry.key == $originalVersion) selected="selected"#end> $services.localization.render("extensions.upgrade.mergeConflict.changes.versionToCompare.${entry.key.toLowerCase()}") </option> #end #end </select><span class="label">$services.localization.render('extensions.upgrade.mergeConflict.changes.revised')</span><select name="revised"> #if ("$!request.revised" != '') #set ($revisedVersion = $request.revised) #elseif ($question.mergedDocument) #set ($revisedVersion = 'MERGED') #else #set ($revisedVersion = 'NEXT') #end #set ($revisedDocument = $versions.get($revisedVersion)) #foreach($entry in $versions.entrySet()) #if ($entry.value) <option value="$entry.key"#if ($entry.key == $revisedVersion) selected="selected"#end> $services.localization.render("extensions.upgrade.mergeConflict.changes.versionToCompare.${entry.key.toLowerCase()}") </option> #end #end </select>#extensionActionButton('diff' true) </div> #if ($originalDocument && $revisedDocument) <div id="changescontent"> #set ($conflictsList = $question.documentConflicts) #set ($rev1 = $originalVersion.toLowerCase()) #set ($rev2 = $revisedVersion.toLowerCase()) #set ($wrappedDocs = $xwiki.wrapDocs([$originalDocument, $revisedDocument])) #set ($origdoc = $wrappedDocs.get(0)) #set ($newdoc = $wrappedDocs.get(1)) #set ($headingLevel = 4) #template('changesdoc.vm') </div> #end #end #macro (displayExtensionDetails_cleanPagesQuestion $question) <dl> <dt> <label>$escapetool.xml($services.localization.render('extensions.uninstall.cleanPages.label'))</label> <span class="xHint">$escapetool.xml($services.localization.render('extensions.uninstall.cleanPages.hint'))</span> </dt> <dd> #set ($entityReferenceTree = $services.model.toTree($question.pages.keySet())) #displayDocumentTree($entityReferenceTree $question.pages) </dd> </dl> #end #macro (displayDocumentTree $entityReferenceTree $mapOfSelectedDocuments) #set ($currentLocale = $services.localization.currentLocale) #displayDocumentTreeNode($entityReferenceTree $mapOfSelectedDocuments) #end #macro (displayDocumentTreeNode $node $mapOfSelectedDocuments) #if ($node.reference) #set ($nodeLabel = $node.reference.name) #if ("$node.reference.type" == 'WIKI') #set ($wikiPrettyName = $services.wiki.getById($node.reference.name).prettyName) #if ("$!wikiPrettyName.trim()" != '') #set ($nodeLabel = $wikiPrettyName) #end #end <div class="$!node.reference.type.toString().toLowerCase() node">$escapetool.xml($nodeLabel) #if ("$node.reference.type" == 'DOCUMENT') ## Currently there's no string representation of a document reference with parameters (such as locale) that can ## be resolved so we need to submit a set of (document reference without locale, locale) pairs. #set ($name = $escapetool.xml($services.model.serialize($node.reference, 'default'))) ## We don't display the locale child nodes if there is only one locale. We display just the document node. #if ($node.locales && $node.locales.size() == 1) #set ($documentReference = $node.locales.iterator().next()) #if ("$!documentReference.locale" != '') ## Display the locale if it's not the default one. <span class="locale">$escapetool.xml($documentReference.locale.getDisplayName($currentLocale))</span> #end <span class="actions"> <input type="checkbox" name="$name" value="$escapetool.xml("$!documentReference.locale")" #if ($mapOfSelectedDocuments.get($documentReference)) checked="checked"#end /> </span> #end #end </div> #end #if ($node.children && $node.children.size() > 0) <ul#if (!$node.reference) class="collapsible selectable document-tree"#end> #foreach ($child in $node.children) <li#if ("$!child.reference.type" == 'DOCUMENT') class="collapsed"#end> #displayDocumentTreeNode($child $mapOfSelectedDocuments) </li> #end </ul> #elseif ($node.locales && $node.locales.size() > 1) <ul> #foreach ($documentReference in $node.locales) #if ("$!documentReference.locale" == '') #set ($locale = $services.localization.render( 'platform.extension.distributionWizard.reportStepDocumentsDefaultLanguage')) #else #set ($locale = $documentReference.locale.getDisplayName($currentLocale)) #end <li class="locale node">$escapetool.xml($locale) <span class="actions"> <input type="checkbox" name="$name" value="$escapetool.xml("$!documentReference.locale")" #if ($mapOfSelectedDocuments.get($documentReference)) checked="checked"#end /> </span> </li> #end </ul> #end #end #macro (displayExtensionDetails_defaultConflictActionQuestion $question) <dl> <dt> <label>$services.localization.render('extension.xar.question.defaultConflictAction.label')</label> <span class="xHint">$services.localization.render('extension.xar.question.defaultConflictAction.hint')</span> </dt> <dd> <dl> #foreach ($conflictType in $services.extension.xar.conflictTypes) #set ($defaultConflictAction = $question.getConflictAction($conflictType)) <dt> <label>$services.localization.render("extension.xar.conflict.${conflictType}.label")</label> <span class="xHint">$services.localization.render("extension.xar.conflict.${conflictType}.hint")</span> </dt> <dd> <select name="defaultConflictAction_$conflictType"> #foreach ($conflictAction in $conflictType.actions) <option value="$conflictAction" label="$services.localization.render("extension.xar.conflict.action.${conflictAction}.hint")"#if ($conflictAction == $defaultConflictAction) selected="selected"#end> $services.localization.render("extension.xar.conflict.action.${conflictAction}.label") </option> #end </select> </dd> #end </dl> </dd> </dl> #end #macro (answerExtensionJobQuestion_defaultConflictActionQuestion $question) #foreach ($conflictType in $services.extension.xar.conflictTypes) #set ($conflictAction = $request.getParameter("defaultConflictAction_$conflictType")) #if ($conflictAction) #set ($void = $question.setConflictAction($conflictType, $conflictAction)) #end #end #end #macro (getBackwardDependencies $extension $return) #getInstalledExtension($extension $extensionNamespace $installedExtension) #if ($installedExtension.isInstalled($NULL)) ## The extension is installed in the root namespace so it can have backward dependencies on multiple namespaces. #set ($backwardDependencies = $services.extension.installed.getBackwardDependencies($installedExtension.id)) #if ($backwardDependencies && ($xcontext.isMainWiki() || $backwardDependencies.containsKey($extensionNamespace))) #if (!$xcontext.isMainWiki()) ## If we're not on the main wiki then display only the backward dependencies from the current namespace. #set ($backwardDependencies = {$extensionNamespace: $backwardDependencies.get($extensionNamespace)}) #end #else #set ($backwardDependencies = {}) #end #elseif ($installedExtension) ## The extension is installed on the current namespace. #set ($backwardDependencies = $services.extension.installed.getBackwardDependencies($installedExtension.id.id, $extensionNamespace)) #if ($backwardDependencies && $backwardDependencies.size() > 0) #set ($backwardDependencies = {$extensionNamespace: $backwardDependencies}) #else #set ($backwardDependencies = {}) #end #else #set ($backwardDependencies = {}) #end #set ($return = $NULL) #setVariable("$return" $backwardDependencies) #end #macro (displayExtensionDetails $extension) <div class="extension-body"> #set ($extensionIdHashCode = "$extensionNamespace/$extension.id.id/$extension.id.version.value") #set ($extensionIdHashCode = $extensionIdHashCode.hashCode()) #getBackwardDependencies($extension $backwardDependencies) #displayExtensionDetails_menu($extension) #displayExtensionDetails_description($extension) #displayExtensionDetails_dependencies($extension $backwardDependencies) #displayExtensionDetails_changes($extension) #displayExtensionDetails_progress($extension) </div> #end #macro (displayExtension $extension $readOnly) ## The job status can change while the extension is displayed so we cache it. Let's reset the cache. #set ($jobStatus = $NULL) #isShowingExtensionDetails($extension $showExtensionDetails) #determineExtensionStatus($extension $extensionStatus $extensionStatusMessage) <form action="$xwiki.relativeRequestURL" method="post" class="extension-item extension-item-${extensionStatus}"> <div class="hidden"> <input name="readOnly" value="$!readOnly" type="hidden" /> <input name="extensionId" value="$!escapetool.xml($extension.id.id)" type="hidden" /> <input name="extensionVersion" value="$!escapetool.xml($extension.id.version.value)" type="hidden" /> <input name="extensionNamespace" value="$!escapetool.xml($extensionNamespace)" type="hidden" /> #if ($request.section) <input name="section" value="$escapetool.xml($request.section)" type="hidden" /> #end #if ($request.viewer) ## Send the AJAX requests to the specified viewer (Velocity template). This is needed for instance when the ## Extension Manager UI is not installed. <input name="xpage" value="$escapetool.xml($request.viewer)" type="hidden" /> #end </div> <div class="extension-header"> <h2 class="extension-title"> <span class="extension-name">#displayExtensionName($extension)</span> <span class="extension-version">$escapetool.xml($extension.id.version)</span> </h2> #if ($extensionStatusMessage) <p class="extension-status">$escapetool.xml($extensionStatusMessage)</p> #end #displayExtensionActionButtons($extension, $readOnly) #displayExtensionRating($extension) #if ($extension.authors.size() > 0) #displayExtensionAuthors($extension) #end #if ("$!extension.summary" != '') <div class="extension-summary">$escapetool.xml($extension.summary)</div> #end #if ($extension.isRecommended()) <div class="extension-recommended">$services.localization.render('extensions.info.recommended')</div> #end #displayProgressBar($extension) <div class="clearfloats"></div> </div> #if ($showExtensionDetails) #displayExtensionDetails($extension) #end </form> #end #macro (handleExtensionRequest) #if ($request.form_token) #if ($services.csrf.isTokenValid($request.form_token)) #handleExtensionAction(true) #elseif ($isAjaxRequest) ## The CSRF token expired. We only redisplay the extension because the resubmission confirmation doesn't fit nicely in-line. $response.sendRedirect("#getExtensionURL()") #else $response.sendRedirect($services.csrf.getResubmissionURL()) #end #else #handleExtensionAction(false) #end #end #macro (handleExtensionAction $withValidToken) #if ($request.extensionAction == 'continue' && $withValidToken) #continueExtensionJob($request.extensionId $request.extensionVersion) #elseif ($request.extensionAction == 'repairXAR' && $withValidToken) #repairXarExtension($request.extensionId $request.extensionVersion) #elseif ($request.extensionAction == 'install' || $request.extensionAction == 'upgrade' || $request.extensionAction == 'downgrade') #computeInstallPlan($request.extensionId $request.extensionVersion $extensionNamespace) #elseif ($request.extensionAction == 'installGlobally') #computeInstallPlan($request.extensionId $request.extensionVersion $NULL) #elseif ($request.extensionAction == 'upgradeGlobally' || $request.extensionAction == 'downgradeGlobally') #computeUpgradePlan($request.extensionId $request.extensionVersion) #elseif ($request.extensionAction == 'uninstall') #computeUninstallPlan($request.extensionId $request.extensionVersion $extensionNamespace) #elseif ($request.extensionAction == 'uninstallGlobally') #computeUninstallPlan($request.extensionId $request.extensionVersion $NULL) #elseif ($request.extensionAction == 'diffXAR') #diffXarExtension($request.extensionId $request.extensionVersion) #elseif ($request.extensionAction == 'revertDocument' && $withValidToken) #revertDocument($request.documentReference $request.documentLocale $request.documentExtensionId $request.documentExtensionVersion, $request.extensionId) #elseif ($request.extensionVersionConstraint) #set ($dependency = $extensionManager.createExtensionDependency($request.extensionId, $request.extensionVersionConstraint)) #displayDependency($dependency $extensionNamespace true) #else ## Display the extension. ## Create a dependency in order to support version constraints (e.g. a version range). #set ($readOnly = $request.readOnly == 'true') #set ($dependency = $extensionManager.createExtensionDependency($request.extensionId, $request.extensionVersion)) #if ($dependency.versionConstraint.version && $dependency.versionConstraint.ranges.isEmpty()) ## A precise version was specified so we resolve the requested extension. #set ($extension = $extensionManager.resolve($request.extensionId, $request.extensionVersion)) #else ## A version range was specified so we resolve the requested extension dependency. Note that the result might not ## be exactly the requested extension but some extension that provides / features the requested extension. #set ($extension = $extensionManager.resolve($dependency, $extensionNamespace)) #end #if ($extension) #displayExtension($extension, $readOnly) #else <div class="infomessage">$services.localization.render('extensions.advancedSearch.noResults', ["<strong>$!escapetool.xml($request.extensionId)</strong>", "<strong>$!escapetool.xml($request.extensionVersion)</strong>"])</div> ## DEBUG START: Check if there is any job status associated with the specified extension. #getExtensionJobStatus($request.extensionId, $request.extensionVersion $jobStatus) #if ($jobStatus) ## Normally we shouldn't get here. <div class="errormessage">We found an extension job associated with the missing extension:</div> #displayExtensionJobStatus($jobStatus) #end ## DEBUG STOP #end #end #end #macro (computeInstallPlan $extensionId $extensionVersion $extensionNamespace) #set ($installPlanRequest = $extensionManager.createInstallPlanRequest($extensionId, $extensionVersion, $extensionNamespace)) #if ($extensionConfig.skipCheckRight) #set ($discard = $installPlanRequest.removeProperty('checkrights')) #end #if ($extensionConfig.skipCurrentUser) #set ($discard = $installPlanRequest.removeProperty('user.reference')) #end #if ($extensionConfig.installJAROnRoot) #set ($discard = $installPlanRequest.rewriter.installExtensionTypeOnRootNamespace('jar')) #set ($discard = $installPlanRequest.rewriter.installExtensionTypeOnRootNamespace('webjar')) #end #set ($discard = $extensionManager.createInstallPlan($installPlanRequest)) #handleExtensionJobStartFailure('extensions.install.error.prepareFailure') #end #macro (computeUpgradePlan $extensionId $extensionVersion) ## Upgrade all the namespaces were the specified extension is installed. #set ($namespaces = []) #foreach ($extension in $extensionManager.installedExtensions) #if ($extension.id.id == $extensionId) #if ($extension.isInstalled($NULL)) #set ($discard = $namespaces.clear()) #break #else #foreach ($namespace in $extension.namespaces) #set ($discard = $namespaces.add($namespace)) #end #end #end #end ## The namespace that will appear in the job id. #set ($jobIdNamespace = $NULL) #if ($namespaces.size() == 1) #set ($jobIdNamespace = $namespaces.get(0)) #end #set ($installPlanRequest = $extensionManager.createInstallPlanRequest($extensionId, $extensionVersion, $jobIdNamespace)) #foreach ($namespace in $namespaces) #set ($discard = $installPlanRequest.addNamespace($namespace)) #end #set ($discard = $extensionManager.createInstallPlan($installPlanRequest)) #handleExtensionJobStartFailure('extensions.install.error.prepareFailure') #end #macro (computeUninstallPlan $extensionId $extensionVersion $extensionNamespace) #set ($discard = $extensionManager.createUninstallPlan($extensionId, $extensionNamespace)) #handleExtensionJobStartFailure('extensions.uninstall.error.prepareFailure') #end #macro (continueExtensionJob $extensionId $extensionVersion) #getExtensionJobStatus($extensionId $extensionVersion $jobStatus) #set ($jobState = $jobStatus.state) #set ($jobType = $jobStatus.jobType) #if ($jobState == 'FINISHED') #isExtensionPlan($jobStatus $isExtensionPlan) #if ($isExtensionPlan) ## Execute the latest extension job plan. ## TODO: Would be nice to reuse somehow the job request that was used to create the plan. #if ($jobType == 'installplan') #installExtension($extensionId $extensionVersion $jobStatus.request) #break #elseif ($jobType == 'uninstallplan') #uninstallExtension($extensionId $extensionVersion $jobStatus.request) #break #end #end #elseif ($jobState == 'WAITING') #answerExtensionJobQuestion($jobStatus) #end ## Redirect to extension display. $response.sendRedirect("#getExtensionURL()") #end #macro(revertDocument $documentReference $documentLocale $documentExtensionId $documentExtensionVersion $jobExtensionId) ## Create instance of ExtensionId #set ($extensionId = $services.extension.createExtensionId($documentExtensionId, $documentExtensionVersion)) ## Create instance of DocumentRefernce with the Locale #set ($documentReferenceWithLocale = $services.model.createDocumentReference($services.model.resolveDocument($documentReference), $services.localization.toLocale($documentLocale))) ## Revert the document to the extension state #if (!$services.extension.xar.reset($documentReferenceWithLocale, $extensionId, $services.extension.xar.getDiffJobId($jobExtensionId, $extensionNamespace))) $response.sendError(500, $services.localization.render('extensions.xar.resetDocument.error')) #end #end #macro (answerExtensionJobQuestion $jobStatus) ## Continue an interactive extension job using the data submitted by the user. #set ($question = $jobStatus.question) #set ($questionType = $question.getClass().getName()) #if ($questionType.endsWith('.ConflictQuestion')) ## A merge conflict occurred during installation. #set ($discard = $question.setGlobalAction($request.versionToKeep)) #set ($discard = $question.setAlways($request.autoResolve.equals('true'))) #set ($allDecisions = $request.getParameterValues("conflict_decision_select")); #set ($allCustoms = $request.getParameterValues("conflict_decision_value_custom")) #foreach($conflictReference in $request.getParameterValues("conflict_id")) #set ($decision = $allDecisions[$foreach.index]) #set ($custom = $allCustoms[$foreach.index]) #set ($discard = $question.setConflictDecision($conflictReference, $decision, $custom)) #end #elseif ($questionType.endsWith('.CleanPagesQuestion')) #foreach ($entry in $question.pages.entrySet()) ## Currently there's no string representation of a document reference with parameters (such as locale) that can ## be resolved so what has been submitted is a set of (document reference without locale, locale) pairs. #set ($stringReferenceWithoutLocale = $services.model.serialize($entry.key, 'default')) #set ($localesToDelete = $request.getParameterValues($stringReferenceWithoutLocale)) #set ($delete = $localesToDelete && $localesToDelete.contains($entry.key.locale.toString())) #set ($discard = $entry.setValue($delete)) #end #elseif ($questionType.endsWith('.DefaultConflictActionQuestion')) #answerExtensionJobQuestion_defaultConflictActionQuestion($question) #end #set ($discard = $jobStatus.answered()) #end #macro (installExtension $extensionId $extensionVersion $installRequest) #set ($discard = $extensionManager.install($installRequest)) #handleExtensionJobStartFailure('extensions.install.error.installFailure') #end #macro (uninstallExtension $extensionId $extensionVersion $uninstallRequest) #set ($discard = $extensionManager.uninstall($uninstallRequest)) #handleExtensionJobStartFailure('extensions.uninstall.error.uninstallFailure') #end #macro (repairXarExtension $extensionId $extensionVersion) #if ($extensionNamespace.startsWith('wiki:')) #set ($wikiName = $extensionNamespace.substring(5)) #else #set ($wikiName = $xcontext.database) #end #set ($discard = $services.extension.xar.repairInstalledExtension($extensionId, $extensionVersion, $wikiName)) #handleExtensionJobStartFailure('extensions.install.error.repairXarFailure' $services.extension.xar) #end #macro (diffXarExtension $extensionId $extensionVersion) #if ($extensionNamespace.startsWith('wiki:')) #set ($wikiName = $extensionNamespace.substring(5)) #else #set ($wikiName = $xcontext.database) #end #set ($discard = $services.extension.xar.diff($extensionId, $wikiName)) #handleExtensionJobStartFailure('extensions.install.error.diffXarFailure' $services.extension.xar) #end #macro (handleExtensionJobStartFailure $errorMessageKey $scriptService) #if ($scriptService) #set ($lastError = $scriptService.lastError) #else #set ($lastError = $extensionManager.lastError) #end #if ($lastError) #set ($errorMessage = $services.localization.render($errorMessageKey, [$extensionId, $extensionVersion])) #if ($isAjaxRequest) ## Send error back. $response.sendError(400, $errorMessage) #else <div class="errormessage">$errorMessage #printThrowable($lastError)</div> #end #else ## Redirect to extension display. $response.sendRedirect("#getExtensionURL($extensionId $extensionVersion {'extensionSection': 'progress'})") #end #end #macro (determineExtensionStatus $extension $_extensionStatus $_extensionStatusMessage $versionConstraint) #set ($currentVersion = $NULL) #if (!$jobStatus || !$jobStatus.request.extensions.contains($extension.id)) #getExtensionJobStatus($extension.id.id $extension.id.version.value $jobStatus) #set ($jobState = $jobStatus.state) #end #if ($jobStatus && $jobState != 'FINISHED') #set ($status = 'loading') #else #if ($extension.isInstalled($extensionNamespace)) ## Determine if the extension is still valid. #if ("$!extension.isValid($extensionNamespace)" == 'false') #set ($status = 'installed-invalid') #elseif ($extension.isDependency($extensionNamespace)) #set ($status = 'installed-dependency') #else #set ($status = 'installed') #end #elseif ($extension.repository.descriptor.id == 'core') #set ($status = 'core') #else ## An extension, either local or remote, that might be available to install. ## Check if a different version of this extension is installed or is a core dependency. #set ($currentVersion = $services.extension.core.getCoreExtension($extension.id.id)) #if (!$currentVersion) #getInstalledExtension($extension $extensionNamespace $currentVersion) #end #if ($currentVersion) #set ($status = "#determineVersionCompatibility($extension $currentVersion $versionConstraint)") #else #set ($status = 'remote') #end #end #end #set ($message = $NULL) #if ($status != 'remote' && $status != 'loading') #set ($message = $services.localization.render("extensions.info.status.${status}", [$currentVersion.id.version.value])) #end #set ($_extensionStatus = $NULL) #setVariable ("$_extensionStatus" $status) #set ($_extensionStatusMessage = $NULL) #setVariable ("$_extensionStatusMessage" $message) #end #macro (determineVersionCompatibility $alice $bob $versionConstraint) #set ($prefix = '') #if (!$alice.id.equals($bob.id)) #set ($prefix = 'remote-') #end #set ($suffix = '') #if ($versionConstraint && !$versionConstraint.isCompatible($bob.id.version)) #set ($suffix = '-incompatible') #elseif ("$!bob.isValid($extensionNamespace)" == 'false') #set ($suffix = '-invalid') #elseif ($bob.isDependency($extensionNamespace)) #set ($suffix = '-dependency') #end ${prefix}${bob.repository.descriptor.id}${suffix}## #end #macro (getExtensionJobStatus $extensionId $extensionVersion $return) ## Retrieve the job status for the current wiki and for the entire farm (if the current wiki is the main wiki). #getExtensionJobStatusForNamespace($extensionId $extensionVersion $extensionNamespace $jobStatusForWiki) #if ($xcontext.isMainWiki()) #getExtensionJobStatusForNamespace($extensionId $extensionVersion $NULL $jobStatusForFarm) #end #set ($return = $NULL) #if (!$jobStatusForWiki) #setVariable ("$return" $jobStatusForFarm) #elseif (!$jobStatusForFarm) #setVariable ("$return" $jobStatusForWiki) ## Return the most recent job status. ## No start date means the job was scheduled but hasn't started yet. #elseif (!$jobStatusForFarm.startDate || ($jobStatusForWiki.startDate && $jobStatusForFarm.startDate.after($jobStatusForWiki.startDate))) #setVariable ("$return" $jobStatusForFarm) #else #setVariable ("$return" $jobStatusForWiki) #end #end #macro (getExtensionJobStatusForNamespace $extensionId $extensionVersion $extensionNamespace $return) ## Retrieve the latest job status stored for the specified extension. #set ($_jobStatus = $extensionManager.getExtensionJobStatus($extensionId, $extensionNamespace)) #if ($_jobStatus) ## Check if the job status matches the extension version. #set ($targetVersion = $_jobStatus.request.extensions.get(0).version) #if (!$targetVersion) ## Some jobs don't require the extension version. Let's determine the currently available version. #set ($_extension = $services.extension.resolve($extensionId, $extensionVersion)) #getInstalledExtension($_extension $extensionNamespace $installedExtension) #set ($targetVersion = $installedExtension.id.version) #end #if ($targetVersion && $extensionVersion != $targetVersion.value) #set ($_jobStatus = $NULL) #end #end ## Retrieve the latest plan stored for the specified extension. #set ($_plan = $extensionManager.getExtensionPlanJobStatus($extensionId, $extensionNamespace)) #if ($_plan) ## Check if the plan matches the extension version. #set ($targetVersion = $_plan.request.extensions.get(0).version) #if (!$targetVersion) ## Some jobs don't require the extension version. Let's determine the currently available version. #set ($_extension = $services.extension.resolve($extensionId, $extensionVersion)) #getInstalledExtension($_extension $extensionNamespace $installedExtension) #set ($targetVersion = $installedExtension.id.version) #end #if ($targetVersion && $extensionVersion != $targetVersion.value) #set ($_plan = $NULL) #end #end #set ($return = $NULL) #if (!$_jobStatus) #setVariable ("$return" $_plan) #elseif (!$_plan) #setVariable ("$return" $_jobStatus) ## Return the most recent one between the job status and the plan. ## No start date means the job/plan was scheduled but hasn't started yet. #elseif (!$_jobStatus.startDate || ($_plan.startDate && $_jobStatus.startDate.after($_plan.startDate))) #setVariable ("$return" $_jobStatus) #else #setVariable ("$return" $_plan) #end #end #macro (getInstalledExtension $_extension $namespace $installedExtension) #set ($features = []) #if ($_extension) #set ($discard = $features.addAll($_extension.extensionFeatures)) #set ($discard = $features.add($_extension.id)) #end #set ($discard = $collectionstool.reverse($features)) #set ($return = $NULL) #foreach ($feature in $features) #set ($return = $services.extension.installed.getInstalledExtension($feature.id, $namespace)) #if ($return) #break #end #end #set ($installedExtension = $NULL) #setVariable("$installedExtension" $return) #end #macro (getExtensionURL $extensionId $extensionVersion $extraParams) #set ($parameters = {}) ## #if ($extraParams) #set ($discard = $parameters.putAll($extraParams)) #end ## #if ($extensionId) #set ($discard = $parameters.put('extensionId', $extensionId)) #elseif ($request.extensionId) #set ($discard = $parameters.put('extensionId', $request.extensionId)) #end ## #if ($extensionVersion) #set ($discard = $parameters.put('extensionVersion', $extensionVersion)) #elseif ($request.extensionVersion) #set ($discard = $parameters.put('extensionVersion', $request.extensionVersion)) #end ## #if ($request.extensionNamespace) #set ($discard = $parameters.put('extensionNamespace', $request.extensionNamespace)) #end ## #if ($xback) #set ($discard = $parameters.put('xback', $xback)) #elseif ($request.xback) #set ($discard = $parameters.put('xback', $request.xback)) #end ## ## Copy known parameters. #foreach ($paramName in ['section', 'xpage', 'viewer']) #set ($paramValue = $request.getParameter($paramName)) #if ("$!paramValue" != '') #set ($discard = $parameters.put($paramName, $paramValue)) #end #end ## $doc.getURL($xcontext.action, $escapetool.url($parameters))## #end #macro (computeXBack) #set ($xback = "$!{request.xback}") #if ($xback == '') #set ($params = '') #foreach ($parameterName in $request.parameterNames) #if (!$parameterName.startsWith('extension')) #foreach ($value in $request.getParameterValues($parameterName)) #set ($params = "${params}&${parameterName}=${value}") #end #end #end #if ($params.length() > 0) #set ($params = $params.substring(1)) #end #set ($xback = $doc.getURL($xcontext.action, $params)) #end #end #macro (em_submitButton $value $_name $secondary $extraClassName) <span class="buttonwrapper"> <input type="submit" value="$escapetool.xml($services.localization.render($value))"#if($_name) name="$escapetool.xml($_name)"#end class="button#if($secondary) secondary#end#if($extraClassName) $!escapetool.xml($extraClassName)#end"/> </span> #end #macro (em_linkButton $href $label $extraClassName) <span class="buttonwrapper"> <a href="$escapetool.xml($href)" class="button secondary#if($extraClassName) $!escapetool.xml($extraClassName)#end"> $services.localization.render($label) </a> </span> #end #macro(extensionActionButtons $extension $action $secondary) #extensionActionButtonsWithDisplayHint($extension $action $action $secondary $extraClassName) #end #macro(extensionActionButtonsWithDisplayHint $extension $action $displayHint $secondary) #set ($isGlobalActionSecondary = $secondary) #set ($globalActionExtraClassName = $NULL) #if (!$installedExtension || ($installedExtension.isInstalled($extensionNamespace) && !$installedExtension.isInstalled($NULL))) ## Button that targets only the current wiki. #extensionActionButtonWithDisplayHint($action $displayHint $secondary) #set ($isGlobalActionSecondary = true) ## Indicate that the local action is available. #set ($globalActionExtraClassName = 'alternative-action') #end ## Button that targets the entire farm. #extensionActionGlobalButtonWithDisplayHint($action $displayHint, $isGlobalActionSecondary $globalActionExtraClassName) #end #macro (extensionActionGlobalButton $action $secondary $extraClassName) #extensionActionGlobalButtonWithDisplayHint($action $action $secondary $extraClassName) #end #macro (extensionActionGlobalButtonWithDisplayHint $action $displayHint $secondary $extraClassName) #if ($xcontext.isMainWiki()) #extensionActionButtonWithDisplayHint("${action}Globally" "${displayHint}Globally", $secondary $extraClassName) #end #end #macro (extensionActionButton $action $secondary $extraClassName) #extensionActionButtonWithDisplayHint($action $action $secondary $extraClassName) #end #macro (extensionActionButtonWithDisplayHint $action $displayHint $secondary $extraClassName) #set ($classNames = []) #if ($secondary) #set ($discard = $classNames.add('secondary')) #end #if ($extraClassName) #set ($discard = $classNames.add($extraClassName)) #end #set ($hintKey = "extensions.actions.${displayHint}.hint") <span class="buttonwrapper"> <button type="submit" name="extensionAction" value="$escapetool.xml($action)" #if ($classNames.size() > 0) class="$escapetool.xml($stringtool.join($classNames, ' '))"#end #if ($services.localization.get($hintKey)) title="$escapetool.xml($services.localization.render($hintKey))"#end> $escapetool.xml($services.localization.render("extensions.actions.${displayHint}"))</button> </span> #end #macro (wikiHomePageLink $namespace) #set ($wikiName = $stringtool.removeStart($namespace, 'wiki:')) #set ($wikiReference = $services.model.createDocumentReference($wikiName, '', '').wikiReference) #set ($wikiHomeDocumentReference = $services.model.resolveDocument('', 'default', $wikiReference)) #set ($wikiPrettyName = $services.wiki.getById($wikiName).prettyName) #if ("$!wikiPrettyName.trim()" == '') #set ($wikiPrettyName = $wikiName) #end <a href="$escapetool.xml($xwiki.getURL($wikiHomeDocumentReference))">$escapetool.xml($wikiPrettyName)</a>## #end #macro (isShowingExtensionDetails $extension $_showDetails) ## Show the extension details if this extension has been explicitely requested. #set ($return = "$!request.hideExtensionDetails" != 'true' && $request.extensionId == $extension.id.id && $request.extensionVersion == $extension.id.version.value) #if (!$return) #if (!$jobStatus || !$jobStatus.request.extensions.contains($extension.id)) #getExtensionJobStatus($extension.id.id $extension.id.version.value $jobStatus) #set ($jobState = $jobStatus.state) #end ## Always show the extension details if the extension has a job waiting. #set ($return = $jobState == 'WAITING') #end #set ($_showDetails = $NULL) #setVariable("$_showDetails" $return) #end #macro (displayExtensionUpdaterPlan $plan) #if ($plan.error) #displayExtensionUpdaterPlanStatus($plan) #else ## Group extensions by status (invalid/outdated) and by namespace. #set ($invalid = {}) #set ($outdated = {}) ## Iterate the first level nodes from the upgrade plan tree. #foreach ($firstLevelNode in $plan.tree) #set ($planAction = $firstLevelNode.action) #set ($status = $NULL) #getInstalledExtension($planAction.extension $planAction.namespace $installedVersion) #if (!$installedVersion.isValid($planAction.namespace)) #set ($status = $invalid) ## Check if the latest version has been installed after the upgrade plan was created. #elseif ($installedVersion.id.version.value != $planAction.extension.id.version.value) #set ($status = $outdated) #end #if ($status) #set ($statusForNamespace = $status.get($planAction.namespace)) #if (!$statusForNamespace) #set ($statusForNamespace = []) #set ($discard = $status.put($planAction.namespace, $statusForNamespace)) #end #set ($discard = $statusForNamespace.add($planAction)) #end #end ## #if ($outdated.isEmpty() && $invalid.isEmpty()) <div class="successmessage"> $services.localization.render('platform.extension.updater.noUpdatesAvailable') </div> #else #displayExtensionUpdaterPlanActionByNamespace($invalid 'invalid') #displayExtensionUpdaterPlanActionByNamespace($outdated 'outdated') #end #end #end #macro(displayExtensionUpdaterPlanStatus $status) ## The status is null after the job is created, until the job is scheduled. #set ($isLoading = !$status || ($status.log.isEmpty() && $status.state != 'FINISHED')) <div class="extension-body-progress#if ($isLoading) loading#end"> #if ($status) #printStatusLog($status) #end </div> #end #macro(displayExtensionUpdaterPlanActionByNamespace $actionByNamespace $key) #if (!$actionByNamespace.isEmpty()) <div class="xLabel"> $services.localization.render("platform.extension.updater.${key}ExtensionsLabel") </div> #end ## Sort the extensions by namespace and by their name. #set ($items = []) #foreach ($entry in $actionByNamespace.entrySet()) #foreach ($planAction in $entry.value) #set ($namespace = $entry.key) #set ($namespacePrettyName = $namespace) #if ($stringtool.indexOf($namespace, ':') >= 0) #set ($namespacePrettyName = $stringtool.substringAfter($namespace, ':')) #if ($namespace.startsWith('wiki:')) #set ($wikiPrettyName = $services.wiki.getById($namespacePrettyName).prettyName) #if ("$!wikiPrettyName.trim()" != '') #set ($namespacePrettyName = $wikiPrettyName) #end #end #end #set ($extension = $planAction.extension) #set ($extensionName = "#displayExtensionName($extension)") #set ($discard = $items.add({ 'namespace': $namespace, 'namespacePrettyName': "$!namespacePrettyName", 'extension': $extension, 'extensionName': $extensionName.trim() })) #end #end #set ($items = $sorttool.sort($items, ['namespacePrettyName', 'extensionName'])) ## Paginate the extensions. #set ($hasPagination = false) ## We don't load the pagination CSS here (noSx:true) because the upgrade plan can be loaded through AJAX so ## the Skin Extension hooks might not be available. We load the pagination CSS elsewhere. #set ($paginationParams = { 'defaultItemsPerPage': 5, 'itemParamName': "${key}FirstIndex", 'itemsPerPageParamName': "${key}PerPage", 'noSx': true }) #paginationPrepareParams($paginationParams) #set ($hasPagination = $items.size() > $paginationParams.itemsPerPage) #set ($indexOutOfRange = $items.size() > 0 && $paginationParams.firstItem >= $items.size()) #if ($hasPagination || $indexOutOfRange) #set ($paginationParams.totalItems = $items.size()) #set ($requestParams = {}) #set ($discard = $requestParams.putAll($request.getParameterMap())) #set ($discard = $requestParams.remove($paginationParams.itemParamName)) #set ($discard = $requestParams.remove($paginationParams.itemsPerPageParamName)) #if ($indexOutOfRange) #if ($!request.get("${key}PagingReset")) ## it seems we already got redirected. how this? #set ($paginationParams.firstItem = 0) #else #set ($discard = $requestParams.put("${key}PagingReset", "1")) #set ($redirectUrl = $doc.getURL($xcontext.action, $escapetool.url($requestParams))) #set ($discard = $response.sendRedirect($redirectUrl)) #stop #end #else #set ($discard = $requestParams.remove("${key}PagingReset")) #end #end #if($hasPagination) #set ($paginationParams.url = $doc.getURL($xcontext.action, $escapetool.url($requestParams))) #pagination($paginationParams) #end #set ($lastItem = $mathtool.min($items.size(), $mathtool.add($paginationParams.firstItem, $paginationParams.itemsPerPage))) #if ($request.get("${key}PagingReset")) <div class="box infomessage">$escapetool.xml($services.localization.render('platform.extension.updater.pagingrestart'))</div> #end #set ($items = $items.subList($paginationParams.firstItem, $lastItem)) #foreach ($item in $items) #if ($foreach.index == 0 || $item.namespace != $extensionNamespace) #if ($foreach.index > 0) ## Close the previous group of extensions. </div> #end ## Start a new group of extensions. <div class="xHint"> $services.localization.render("platform.extension.updater.${key}ExtensionsHint", ["#displayExtensionNamespace($item.namespace)"]) </div> <div class="${key}Extensions"> #set ($extensionNamespace = $item.namespace) #end #displayExtension($item.extension) #end #if ($items.size() > 0) ## Close the last group of extensions. </div> #end #if ($hasPagination) #set ($paginationParams.position = 'bottom') #pagination($paginationParams) #end #end #macro (getExtensionUpdaterPlan $_plan) #set ($localPlan = $extensionManager.getExtensionPlanJobStatus($NULL, $extensionNamespace)) #if ($xcontext.isMainWiki()) #set ($globalPlan = $extensionManager.getExtensionPlanJobStatus($NULL, $NULL)) #else #set ($globalPlan = $NULL) #end #set ($_plan = $NULL) #if (!$globalPlan) #setVariable ("$_plan" $localPlan) #elseif (!$localPlan) #setVariable ("$_plan" $globalPlan) ## Return the most recent one between the local plan and the global plan. ## No start date means the plan was scheduled but hasn't started yet. #elseif (!$localPlan.startDate || ($globalPlan.startDate && $localPlan.startDate.after($globalPlan.startDate))) #setVariable ("$_plan" $localPlan) #else #setVariable ("$_plan" $globalPlan) #end #end #macro(computeExtensionUpdaterPlan $_plan $globally) #if ($globally && $xcontext.isMainWiki()) ## Create the upgrade plan for the entire farm. #set ($upgradePlanJob = $extensionManager.createUpgradePlan()) #else ## Create the upgrade plan only for the current wiki. #set ($upgradePlanRequest = $extensionManager.createUpgradePlanRequest($extensionNamespace)) #if ($xcontext.isMainWiki()) ## From the main wiki we can also upgrade the extensions that are installed globally (on the root namespace). #set ($discard = $upgradePlanRequest.addNamespace($NULL)) #end #set ($upgradePlanJob = $extensionManager.createUpgradePlan($upgradePlanRequest)) #end #set ($_plan = $NULL) #setVariable("$_plan" $upgradePlanJob.status) #end #macro (displayExtensionUpdaterTrigger $plan) <form action="$xwiki.relativeRequestURL" method="post"> <div class="hidden"> #if ($xcontext.action == 'view' || $xcontext.action == 'admin') #set ($docAction = 'get') #else #set ($docAction = $xcontext.action) #end ## Compute the URL that will be used to submit the request asynchronously. #if ("$!request.section" != '') ## Administration section. #set ($asyncURL = $xwiki.getURL($request.section, $docAction, $escapetool.url({ 'section': $request.section }))) #else ## Stand-alone or Distribution Wizard. #set ($asyncURL = $doc.getURL($docAction)) #end <input type="hidden" name="asyncURL" value="$!escapetool.xml($asyncURL)" disabled="disabled" /> ## Redirect back to view mode after a POST request. <input type="hidden" name="xredirect" value="$!escapetool.xml($xwiki.relativeRequestURL)" /> </div> #set ($disabled = $plan && $plan.state != 'FINISHED') <p class="buttons dynamic-button-group"> #if ($xcontext.isMainWiki() && $plan && !$plan.request.hasNamespaces()) ## The latest upgrade plan was computed for the entire farm so we display the global button first. #displayExtensionUpdaterButton('checkForUpdatesGlobally' $disabled) #end #displayExtensionUpdaterButton('checkForUpdates' $disabled) #if ($xcontext.isMainWiki() && (!$plan || $plan.request.hasNamespaces())) ## On the main wiki we can also compute the upgrade plan for the entire farm. #displayExtensionUpdaterButton('checkForUpdatesGlobally' $disabled) #end </p> </form> #end #macro (displayExtensionUpdaterButton $value $disabled) <span class="buttonwrapper"> <button name="action" value="$value"#if ($disabled) disabled="disabled"#end> $escapetool.xml($services.localization.render("platform.extension.updater.$value")) </button> </span> #end #macro (extensionUpdater) #set ($plan = $NULL) #set ($error = $NULL) #if ($request.action.startsWith('checkForUpdates')) #computeExtensionUpdaterPlan($plan $request.action.equals('checkForUpdatesGlobally')) #set ($error = $extensionManager.lastError) #if ("$!request.xredirect" != '' && !$error) #set ($discard = $response.sendRedirect($request.xredirect)) #break #end #end #if (!$plan) #getExtensionUpdaterPlan($plan) #end #if (!$isAjaxRequest) ## The list of outdated/invalid extensions is paginated so we load the CSS here because the request is not AJAX. ## Make sure the browser won't keep the same version of the resource in cache from one version of XWiki to another #set ($discard = $xwiki.ssfx.use('uicomponents/pagination/pagination.css', {'forceSkinAction': true, 'version': $environmentVersion})) <p class="noitems"> $escapetool.xml($services.localization.render('extension.updater.hint')) </p> #displayExtensionUpdaterTrigger($plan) #end <div class="extensionUpdater"> #if ($error) <div class="errormessage"> $services.localization.render('platform.extension.updater.createUpgradePlanFailure') #printThrowable($error) </div> #elseif ($plan.state == 'FINISHED') <div class="xHint"> $escapetool.xml($services.localization.render('platform.extension.updater.lastCheckDate', [$xwiki.formatDate($plan.endDate)])) </div> #displayExtensionUpdaterPlan($plan) #elseif ($plan) <div class="xHint">$services.localization.render('platform.extension.updater.loading')</div> #displayJobProgressBar($plan) #displayExtensionUpdaterPlanStatus($plan) #end </div> #end